为什么不重新绘制 JPanel 中的按钮?
Why doesnt repaint repaint the button in the JPanel?
我不明白 repaint();有效。
我试图寻找教程,但从未找到任何东西,'similar questions' 上的回答也没有真正帮助。
这是我可以编写的最基本的代码,它应该可以工作,但不能:
static String done = "0";
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setResizable(false);
JPanel panel = new JPanel();
frame.setSize(800, 500);
frame.setLocation(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton end = new JButton(done);
end.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
done += Integer.valueOf(1);
panel.repaint();
}
});
panel.add(ende);
frame.add(panel);
frame.setVisible(true);
}
很明显,这只是一个按钮,点击数字+1 后应该重新绘制。
后续问题:
我如何告诉面板在另一个面板内重新绘制自己?
这是应该工作的基本代码:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
public class Repaint
{
static String done = "0";
public static void main(String[] args)
{
new Repaint();
}
public Repaint()
{
createframe();
}
public void createframe()
{
JFrame frame = new JFrame();
frame.setResizable(false);
JPanel panel = new JPanel();
frame.setSize(800, 500);
frame.setLocation(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Border bo = new LineBorder(Color.black);
JMenuBar bar = new JMenuBar();
bar.setBorder(bo);
JMenu menu = new JMenu("Edit");
JMenuItem stats = new JMenuItem("Edit the button");
stats.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
createbox();
}
});
menu.add(stats);
JLabel end = new JLabel(done);
bar.add(menu);
frame.setJMenuBar(bar);
panel.add(end);
frame.add(panel);
frame.setVisible(true);
}
public void createbox()
{
JFrame framebox = new JFrame();
framebox.setResizable(false);
JPanel panelbox = new JPanel();
framebox.setSize(800, 500);
framebox.setLocation(500, 400);
JButton end = new JButton(done);
end.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
done += String.valueOf(1);
framebox.dispose();
}
});
panelbox.add(end);
framebox.add(panelbox);
framebox.setVisible(true);
}
}
基本上按下第 2 帧中的按钮会使字符串“完成”的数量增加 1。但是它不会在原始框架中重新绘制它。
如果想把JButton
上的数字加1显示出来,就不用用repaint()
方法了。
无关紧要。
相反,您可以使用 setText()
方法。
代码:
JButton end = new JButton(done);
end.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
done = done + "1";
end.setText(done);
}
});
repaint()
method is related to Graphics/Graphics2D
in Java
. It is called when we want to change the look of a component.
好的,尽管我不完全确定你的程序要做什么,但我已经尝试解决你的两个问题。
首先,您接受的答案实际上是错误的。我猜其他评论者忘记了变量 done
实际上是 String
类型,这意味着运算符 +=
实际上不做任何数学运算,它只是附加字符串。简而言之,运算符不会将 1 添加到 done
,而是将文字字符串值 1
附加到 done
。因此,如果 done
的值为 0 并且您单击具有该代码的按钮,它将附加 1,并且 done
现在将具有值 01
。如果您再次单击它,它将构建 String
011
等等。
要修复这个小错误,您只需将 String
解析为 Integer
,然后您就可以在其上使用数学运算符。
关于你的第二个问题,我重新阅读了你的问题和你的代码,现在看来我在对另一个答案的评论中误解了。我试图不改变你的代码的底层逻辑,因此离开了你的关于 JButton
做什么的代码。在您的原始代码中,按钮递增 done
并且按钮应该显示该文本。不过,该按钮也是此框架的关闭操作,因为您在按钮的 actionPerformed()
调用中调用了 dispose()
。
如果这是应该发生的事情(每次按下按钮关闭框架),那么你甚至不需要 WindowListener
或覆盖任何东西,你可以简单地执行你想要的任何东西 actionPerformed()
打电话。
代码:
public class Repaint
{
String done = "0";
JFrame frame;
JPanel panel;
Border bo;
JMenuBar bar;
JMenu menu;
JMenuItem stats;
JLabel endLabel;
JFrame framebox;
JPanel panelbox;
JButton endButton;
public static void main(String[] args)
{
new Repaint();
}
public Repaint()
{
createFrame();
}
public void createFrame()
{
frame = new JFrame();
frame.setResizable(false);
panel = new JPanel();
frame.setSize(800, 500);
frame.setLocation(500, 400);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
bo = new LineBorder(Color.black);
bar = new JMenuBar();
bar.setBorder(bo);
menu = new JMenu("Edit");
stats = new JMenuItem("Edit the button");
stats.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ev)
{
createBox();
}
});
menu.add(stats);
endLabel = new JLabel(done);
bar.add(menu);
frame.setJMenuBar(bar);
panel.add(endLabel);
frame.add(panel);
frame.setVisible(true);
}
public void createBox()
{
framebox = new JFrame();
framebox.setResizable(false);
panelbox = new JPanel();
framebox.setSize(800, 500);
framebox.setLocation(500, 400);
endButton = new JButton(done);
endButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
done = Integer.toString(Integer.parseInt(done) + 1);
endButton.setText(done);
onDispose();
}
});
panelbox.add(endButton);
framebox.add(panelbox);
framebox.setVisible(true);
}
private void onDispose()
{
endLabel.setText(done);
framebox.dispose();
}
}
我最终用 class 变量替换了你所有的局部变量(也许你不需要所有它们都是非局部的,但无论如何)所以你实际上可以调用 JFrame
在 createFrame()
方法之外的实例 frame
。
您可以看到 toString()
和 parseInt()
的调用实际让数学运算符起作用。
endButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
done = Integer.toString(Integer.parseInt(done) + 1);
endButton.setText(done);
onDispose();
}
});
接下来我简单地替换了 JFrame.dispose()
的直接调用并添加了一点 onDispose()
方法,我在其中更新(通过调用 setText()
)标签。在此方法中,您现在基本上可以添加在调用 dispose()
.
之前应该发生的任何事情
private void onDispose()
{
endLabel.setText(done);
framebox.dispose();
}
如果这不是您要找的,请告诉我。
我不明白 repaint();有效。
我试图寻找教程,但从未找到任何东西,'similar questions' 上的回答也没有真正帮助。
这是我可以编写的最基本的代码,它应该可以工作,但不能:
static String done = "0";
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setResizable(false);
JPanel panel = new JPanel();
frame.setSize(800, 500);
frame.setLocation(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton end = new JButton(done);
end.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
done += Integer.valueOf(1);
panel.repaint();
}
});
panel.add(ende);
frame.add(panel);
frame.setVisible(true);
}
很明显,这只是一个按钮,点击数字+1 后应该重新绘制。
后续问题: 我如何告诉面板在另一个面板内重新绘制自己? 这是应该工作的基本代码:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
public class Repaint
{
static String done = "0";
public static void main(String[] args)
{
new Repaint();
}
public Repaint()
{
createframe();
}
public void createframe()
{
JFrame frame = new JFrame();
frame.setResizable(false);
JPanel panel = new JPanel();
frame.setSize(800, 500);
frame.setLocation(500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Border bo = new LineBorder(Color.black);
JMenuBar bar = new JMenuBar();
bar.setBorder(bo);
JMenu menu = new JMenu("Edit");
JMenuItem stats = new JMenuItem("Edit the button");
stats.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
createbox();
}
});
menu.add(stats);
JLabel end = new JLabel(done);
bar.add(menu);
frame.setJMenuBar(bar);
panel.add(end);
frame.add(panel);
frame.setVisible(true);
}
public void createbox()
{
JFrame framebox = new JFrame();
framebox.setResizable(false);
JPanel panelbox = new JPanel();
framebox.setSize(800, 500);
framebox.setLocation(500, 400);
JButton end = new JButton(done);
end.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
done += String.valueOf(1);
framebox.dispose();
}
});
panelbox.add(end);
framebox.add(panelbox);
framebox.setVisible(true);
}
}
基本上按下第 2 帧中的按钮会使字符串“完成”的数量增加 1。但是它不会在原始框架中重新绘制它。
如果想把JButton
上的数字加1显示出来,就不用用repaint()
方法了。
无关紧要。
相反,您可以使用 setText()
方法。
代码:
JButton end = new JButton(done);
end.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
done = done + "1";
end.setText(done);
}
});
repaint()
method is related toGraphics/Graphics2D
inJava
. It is called when we want to change the look of a component.
好的,尽管我不完全确定你的程序要做什么,但我已经尝试解决你的两个问题。
首先,您接受的答案实际上是错误的。我猜其他评论者忘记了变量 done
实际上是 String
类型,这意味着运算符 +=
实际上不做任何数学运算,它只是附加字符串。简而言之,运算符不会将 1 添加到 done
,而是将文字字符串值 1
附加到 done
。因此,如果 done
的值为 0 并且您单击具有该代码的按钮,它将附加 1,并且 done
现在将具有值 01
。如果您再次单击它,它将构建 String
011
等等。
要修复这个小错误,您只需将 String
解析为 Integer
,然后您就可以在其上使用数学运算符。
关于你的第二个问题,我重新阅读了你的问题和你的代码,现在看来我在对另一个答案的评论中误解了。我试图不改变你的代码的底层逻辑,因此离开了你的关于 JButton
做什么的代码。在您的原始代码中,按钮递增 done
并且按钮应该显示该文本。不过,该按钮也是此框架的关闭操作,因为您在按钮的 actionPerformed()
调用中调用了 dispose()
。
如果这是应该发生的事情(每次按下按钮关闭框架),那么你甚至不需要 WindowListener
或覆盖任何东西,你可以简单地执行你想要的任何东西 actionPerformed()
打电话。
代码:
public class Repaint
{
String done = "0";
JFrame frame;
JPanel panel;
Border bo;
JMenuBar bar;
JMenu menu;
JMenuItem stats;
JLabel endLabel;
JFrame framebox;
JPanel panelbox;
JButton endButton;
public static void main(String[] args)
{
new Repaint();
}
public Repaint()
{
createFrame();
}
public void createFrame()
{
frame = new JFrame();
frame.setResizable(false);
panel = new JPanel();
frame.setSize(800, 500);
frame.setLocation(500, 400);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
bo = new LineBorder(Color.black);
bar = new JMenuBar();
bar.setBorder(bo);
menu = new JMenu("Edit");
stats = new JMenuItem("Edit the button");
stats.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ev)
{
createBox();
}
});
menu.add(stats);
endLabel = new JLabel(done);
bar.add(menu);
frame.setJMenuBar(bar);
panel.add(endLabel);
frame.add(panel);
frame.setVisible(true);
}
public void createBox()
{
framebox = new JFrame();
framebox.setResizable(false);
panelbox = new JPanel();
framebox.setSize(800, 500);
framebox.setLocation(500, 400);
endButton = new JButton(done);
endButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
done = Integer.toString(Integer.parseInt(done) + 1);
endButton.setText(done);
onDispose();
}
});
panelbox.add(endButton);
framebox.add(panelbox);
framebox.setVisible(true);
}
private void onDispose()
{
endLabel.setText(done);
framebox.dispose();
}
}
我最终用 class 变量替换了你所有的局部变量(也许你不需要所有它们都是非局部的,但无论如何)所以你实际上可以调用 JFrame
在 createFrame()
方法之外的实例 frame
。
您可以看到 toString()
和 parseInt()
的调用实际让数学运算符起作用。
endButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
done = Integer.toString(Integer.parseInt(done) + 1);
endButton.setText(done);
onDispose();
}
});
接下来我简单地替换了 JFrame.dispose()
的直接调用并添加了一点 onDispose()
方法,我在其中更新(通过调用 setText()
)标签。在此方法中,您现在基本上可以添加在调用 dispose()
.
private void onDispose()
{
endLabel.setText(done);
framebox.dispose();
}
如果这不是您要找的,请告诉我。