为什么重绘不重绘 JPanel 中的按钮?



我不明白repaint((是如何工作的。

我试图寻找教程,但从未找到任何东西,关于"类似问题"的 naswers 也没有真正帮助。

这是我可以编写的最基本的代码,应该可以工作,但不能:

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。但它不会在原始框架中重新粉刷它。

好的,所以我尝试解决你的两个问题,尽管不完全确定你的程序要做什么。

首先,你接受的答案实际上是错误的。我猜另一个评论者忘记了变量done实际上是String类型,这意味着运算符+=实际上并没有做任何数学运算,它只是附加字符串。简单来说,运算符不会将 1 加到done而是将文本字符串值附加到done1。因此,如果done的值为 0,并且您单击带有该代码的按钮,它将附加 1,done现在将具有值01。如果再次单击它,它将构建String011,依此类推。

要修复这个小错误,您只需要将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();
}
}

我最终用类变量替换了所有局部变量(也许您不需要所有变量都是非本地变量,但无论如何(,因此您实际上可以在createFrame()方法之外调用JFrame实例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();
}

如果这不是您要找的,请告诉我。

如果要在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()方法与Java中的Graphics/Graphics2D有关。当我们想要更改组件的外观时,会调用它。

最新更新