- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
最近我在 Swing 方面遇到了一些问题。我正在创建一个需要在 JFrame 和 JPanel 中频繁编辑内容(在本例中为 JButton 上显示的字符串)的项目,我想了解如何执行此操作。
我搜索了很长时间,找到的主要答案是我需要调用 .repaint(),可能在调用 .revalidate() 之后。但是,我无法让我的代码正常运行。
现在,框架将按原样绘制,但按下按钮后,其中的文本不会改变 - 事实上,它会产生一个大错误日志,可在此处查看:https://pastebin.com/7P85cB8h
下面是我的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Actions extends JFrame implements ActionListener
{
JButton Beans;
String String1;
JPanel things;
public static void main (String[] args)
{
new Actions();
}
public Actions()
{
JPanel things = new JPanel();
String1 = "Beans";
this.setSize(400,400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Hello there");
Box theBox = Box.createHorizontalBox();
Beans = new JButton("" + String1);
Beans.addActionListener(this);
theBox.add(Box.createHorizontalStrut(50));
theBox.add(Beans);
this.add(theBox);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
String1 = "Surprise!";
things.revalidate();
things.repaint();
}
}
所以,澄清一下,我有一个 JButton,在 JPanel 中,在 JFrame 中。该按钮本身显示一个字符串,最初显示为“Beans”。当我按下按钮时,我希望字符串现在显示为“Surprise!”。
感谢您的宝贵时间。
最佳答案
您的问题是将对象与引用变量混淆,认为更改 String1 的文本会神奇地导致 JButton 显示的文本发生变化,但这不是 Java 的 OOP 模型的工作方式。了解 JButton 正在显示一个 String 对象,String1 最初引用的是同一个对象,但是当您更改 String1 引用的 String 时,这对原始 String 对象没有影响。为了更改显示的字符串,您必须更改 JButton 显示的字符串对象,方法是调用 JButton 的 setText(...)
方法并将新的字符串传递给它。这是唯一可行的方法。
public void actionPerformed(ActionEvent e) {
Beans.setText("Surprise!");
}
查看评论:
// here are several reference variables
// all without assigned objects, and thus
// all holding "null" values:
JButton Beans;
String String1;
JPanel things;
public Actions() {
//.....
// here you assign the String object, "Beans" to the String1 variable
String1 = "Beans";
// .....
// here you create a JButton and pass in String1's current object, "Beans"
// into the constructor (note the "" + is NOT needed for Strings, only for numberrs)
Beans = new JButton("" + String1);
//.....
}
public void actionPerformed(ActionEvent e) {
// here you change the object that String1 refers to
String1 = "Surprise!";
// but this has no effect on the original String object, "Beans" displayed in the
// JButton, but rather all it does is change the state of String1.
// To change the state of the JButton, you must explicitly do this
// by calling setText on it
//....
顺便说一句,您需要学习和使用 Java naming conventions .变量名应全部以小写字母开头,而类名应以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。
旁注 #2:如果您实际上绘制 字符串,那么您的原始代码就可以工作。请注意,在下面的代码中,我有一个字符串变量 currentString
,它最初指的是字符串数组 TEXTS
中的第一项,字符串 "One"
。在 JButton 的 ActionListener 中,我更新了名为 index
的数组索引变量,并将 currentString
变量设置为数组中的下一个 String 项,然后调用 repaint ()
。这段代码起作用的原因是因为我在 JPanel 的绘画方法 paintComponent(...)
中绘制由 currentString
保存的文本:
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
public class DrawStringPanel extends JPanel {
private static final String[] TEXTS = {
"One", "Two", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Ten"
};
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final Font TEXT_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 40);
private static final int TEXT_X = 150;
private static final int TEXT_Y = 200;
private int index = 0;
// Note that this String variable holds the first item in the TEXTS array
private String currentString = TEXTS[index];
public DrawStringPanel() {
setPreferredSize(new Dimension(PREF_W, PREF_H));
JButton nextBtn = new JButton("Next");
add(nextBtn);
nextBtn.addActionListener(e -> {
// update the array index
index++; // get next index
index %= TEXTS.length; // but don't let get bigger then array length
// and in the ActionListener here I'm changing the variable and calling repaint
// this works because this variable is actually painted within this JPanel's
// paintComponent method....
currentString = TEXTS[index];
repaint();
});
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setFont(TEXT_FONT);
// ****** HERE ****** I draw the contents of the currentString variable
g2.drawString(currentString, TEXT_X, TEXT_Y);
}
private static void createAndShowGui() {
DrawStringPanel mainPanel = new DrawStringPanel();
JFrame frame = new JFrame("DrawStringPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
关于java - 通过 EventListener 调用 repaint() 和/或 revalidate() - Swing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52488908/
我每秒收到数百个事件,持续几秒钟,每个事件都会更新我的模型。如果我在每个事件之后在 invokeLater() 内部调用 repaint() ,那么 repaint 每秒会被调用数百次吗?它是否足够聪
我在类collection中有一个循环,它repaint() JPanel连续 while(loop) { imageicon = (ImageIcon) ois.readOb
我仍在尝试让一个 repaint() 方法在一个单独的类中工作,该类具有一个扩展 JComponent 的类。我已经在这里发布了几篇文章,但到目前为止我还无法让代码正常工作。我得到了一些很好的建议。我
谁能解释一下JPanel.repaint() 方法和JFrame.repaint() 方法之间的区别,我想两者都调用了paintComponent() JPanel 中的方法。 请说明,谢谢 最佳答案
在repaint(long maxDelay)(来自java.awt.Component)中,maxDelay指定之前可以经过的最大毫秒数调用update。 普通的repaint()有这样的最大值吗?
这个问题是基于我不久前遇到的一个简单的 Swing 骰子程序问题。我发布的原始问题是 here并且有一个可接受的答案,但我想确切地知道发生了什么,为什么会出现问题,以及解决方案为什么有效。 我设法削减
我正在为错误程序编写一个插件,并且在使用 repaint() 方法时遇到问题。 简短的问题:有什么方法可以在 JPanel 重绘完成后立即获得通知或与其同步代码吗? 详细版本: 我的程序可以将 xy
我在java中使用2个类class1和class2,它们都位于不同的包中。 class2 中定义了一个 paintComponent() 和一个 test()。我按以下顺序从 class1 调用这些方
Full project here https://github.com/jafetrd/easyImageEditor 我正在尝试使用paintComponent()将颜色应用于图像,这是我使用的类
我正在尝试制作一个 JFrame 程序,将二进制-十进制-十六进制转换器与按钮连接起来。其中一部分,我想绘制圆圈来表示一排圆圈中的二进制数,其中实心圆圈代表一,空心圆圈代表零。但是,当我尝试调用 re
我两周前才开始学习java,所以我对java还不太了解。我正在尝试让一个球在框架内弹跳或移动。但当我在线程中运行它时,它不会重新绘制/更新,但如果我使用 while 循环或计时器,它就可以正常工作,我
我正在尝试制作一款三消游戏。我试图为实际发生的情况创建一些视觉辅助,首先将需要删除的 gem 标记为“黑色”,然后让重力完成它的工作。我正在努力做到这一点,在将它们标记为“黑色”后,我调用了 repa
我正在编写一个 Java 程序,它将根据按下的按钮绘制圆形或矩形。虽然它确实绘制了给定的形状,但在绘制时它会在窗口的左上角(最有可能是(0,0))创建新按钮。我是否违反了paint()/repaint
我正在为学校项目开发一款游戏,一款类似炸弹人的游戏。 我正在使用 swing,并且使用 Canvas 来绘制图形,但 KeyListener 无法正常工作,因此我退出使用 Canvas 并开始使用 p
嘿,我正在尝试学习如何在java中使用图形,并且正在编写一个非常简单的代码,该代码获取图像并将其在窗口中成一条线移动,当它到达窗口边缘时,它会向下移动几个像素并从另一端开始。 我的问题是我的程序在重新
我试图了解 repaint 和 paintComponents 在 Java Swing 中如何工作,并想知道为什么这个程序在执行时只显示“hello”。 class MyLabel extends
我无法让我的重绘方法在我的 SimonPanel 类中工作。起初,我认为这是因为我使用了paint()而不是paintComponent(),但这似乎并没有解决问题。我的 SimonShape.jav
这就是我的任务。 我必须生成 4 张随机卡。之后,当按下“刷新”按钮时,卡片应再次随机化。我已经像这样实现了 repaint() 方法,但它不会改变卡片的显示方式。 public class Four
我看了很多答案,但仍然找不到解决方案。我有一个 JFrame 和两个 JPanel。我想在按下按钮时删除第一个面板并将其替换为第二个面板,但 repaint() 方法不会刷新框架。请帮忙。 这是我的框
我在这里尝试做的是从我的 loadbg() 方法中调用 repaint() 方法。但是,repaint() 不起作用,并且我的图像(存储在 var bg 中)不会加载到屏幕上。关于为什么这行不通的任何
我是一名优秀的程序员,十分优秀!