【发布时间】:2012-10-04 05:45:04
【问题描述】:
我在使用几个按钮来摆动和更新 JPanel 时遇到问题。有时我需要删除或添加甚至修改一些按钮。我已经创建了一个例程来做到这一点,只有很少的对话框和消息框。事实是,有时(随机)JPanel 不能正确刷新(它不会按要求删除按钮,甚至不会添加它)。如果我第二次调用刷新例程(我调用对话框添加一个按钮,然后单击退出而不添加任何内容)一切顺利。我不知道为什么,我认为这是关于时间和需要每个重绘或重新验证方法有效的时间,这个考虑是因为我试图调试程序(使用 eclipse 和几个断点)并且在调试期间它总是刷新正确。
这是一些代码(简化)。
// This method is used when first creating the GUI (the removeAll obviously remove nothing
// I call the revalidate because I re-add the buttons, and I call repaint to have the
// JPanel itself repainted.
public static void repaintServices() {
//services is a JPanel
services.removeAll();
JLabel lbl = new JLabel("SERVIZI");
services.add(lbl);
services.add(Box.createRigidArea(new Dimension(0, 20)));
// ########## SERVICES BUTTONS
Database.connect();
ArrayList<Service> s = Database.listServices();
JPanel btt = new JPanel();
for (int i = 0; i < s.size(); i++) {
JButton b = new JButton(s.get(i).getName().toUpperCase());
if (i % 3 == 0) {
btt = new JPanel();
btt.setLayout(new BoxLayout(btt, BoxLayout.LINE_AXIS));
services.add(btt);
services.add(Box.createRigidArea(new Dimension(0, 10)));
btt.add(b);
} else {
btt.add(Box.createRigidArea(new Dimension(10, 0)));
btt.add(b);
}
}
Database.disconnect();
// ########## END SERVICES BUTTONS
services.add(Box.createVerticalGlue());
services.revalidate();
services.repaint();
}
这是我修改数据库(以及按钮列表)的地方
LOG.finest("User ask to add a new Service");
ArrayList<String> result = GUI.showServiceDialog();
if (result.size() > 0) {
if (!"".equals(result.get(0))) {
String name = result.get(0);
Database.connect();
if (Database.addService(name, price, cadence)) {
GUI.showMessage("Servizio aggiunto correttamente");
GUI.repaintServices();
}
Database.disconnect();
} else {
GUI.showErrorMessage("All field necessary!\nNew Service NOT added");
return;
}
}else {
return;
}
这是用于获取用户插入的值的方法(使用自定义模式对话框)
public static ArrayList<String> showServiceDialog() {
ArrayList<String> ret = new ArrayList<String>();
JTextField name = new JTextField(15);
JTextField price = new JTextField(5);
JTextField cadence = new JTextField(4);
// NOT USEFUL STUFF, just adding some components. JUMP DOWN TO.....
JPanel p = new JPanel();
p.setLayout(new BoxLayout(p, BoxLayout.PAGE_AXIS));
JPanel pp = new JPanel();
pp.setLayout(new BoxLayout(pp, BoxLayout.LINE_AXIS));
pp.add(new JLabel("Nome:"));
pp.add(Box.createHorizontalStrut(10));
pp.add(name);
p.add(pp);
p.add(Box.createVerticalStrut(10)); // a spacer
pp = new JPanel();
pp.setLayout(new BoxLayout(pp, BoxLayout.LINE_AXIS));
pp.add(new JLabel("Prezzo:"));
pp.add(Box.createHorizontalStrut(10));
pp.add(price);
pp.add(new JLabel("€"));
pp.add(Box.createHorizontalStrut(20));
pp.add(new JLabel("Frequenza:"));
pp.add(Box.createHorizontalStrut(10));
pp.add(cadence);
p.add(pp);
p.add(Box.createVerticalStrut(15));
// .... HERE, following the interesting part.
int result = JOptionPane.showConfirmDialog(window, p, "Inserisci i dati del nuovo servizio", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
ret.add(name.getText());
ret.add(price.getText());
ret.add(cadence.getText());
}
return ret;
}
我还有一些其他方法,如删除、编辑等,但问题(不正确刷新)是每种方法随机出现的,我发布了我拥有的最简单的部分。
有什么想法吗? (我对 GUI 的其他部分也有同样的问题,比如组合框或列表框,GUI 是用 SwingUtilities.invokeLater 启动的)
这里有一些 SSCCE 代码,问题发生在: 添加,添加,删除,添加
删除后的添加不能正确刷新(有时,有时是随机的,正如我所说的)。 (不碰任何其他东西)。希望代码够清晰够短,我把貌似没涉及的数据库去掉了。
package it.kApps;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class RevalidateRepaintTry {
private static JPanel services;
private static ArrayList<String> s;
public RevalidateRepaintTry() {
s = new ArrayList<String>();
s.add("btt1");
s.add("btt2");
JFrame main = new JFrame();
main.getContentPane().setLayout(new BoxLayout(main.getContentPane(), BoxLayout.PAGE_AXIS));
services = new JPanel();
repaintServices();
JButton b = new JButton("ADD");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
String add = JOptionPane.showInputDialog("insert new");
s.add(add);
repaintServices();
}
});
JButton bb = new JButton("DEL");
bb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
s.remove(s.size() - 1);
repaintServices();
}
});
main.add(services);
main.add(b);
main.add(bb);
main.setVisible(true);
main.pack();
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String arg[]) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new RevalidateRepaintTry();
}
});
}
public static void repaintServices() {
// services is a JPanel
services.removeAll();
JLabel lbl = new JLabel("SERVIZI");
services.add(lbl);
services.add(Box.createRigidArea(new Dimension(0, 20)));
// ########## SERVICES BUTTONS
JPanel btt = new JPanel();
for (int i = 0; i < s.size(); i++) {
JButton b = new JButton(s.get(i));
if (i % 3 == 0) {
btt = new JPanel();
btt.setLayout(new BoxLayout(btt, BoxLayout.LINE_AXIS));
services.add(btt);
services.add(Box.createRigidArea(new Dimension(0, 10)));
btt.add(b);
} else {
btt.add(Box.createRigidArea(new Dimension(10, 0)));
btt.add(b);
}
}
// ########## END SERVICES BUTTONS
services.add(Box.createVerticalGlue());
services.revalidate();
services.repaint();
}
}
【问题讨论】:
-
“我发布了我拥有的最简单的部分。” 为了尽快获得更好的帮助,请发布SSCCE。
-
谢谢你的回答,问题是我不能写一些简单的东西,因为如果简单的话刷新是没有问题的。顺便说一句,我正在努力!
-
“任何提示?” 是的,很多。我将它们集中在那篇文章中,因为评论对他们来说太小了。 “它不短” 让它简短。该 sn-p 有 3 个标签/文本字段组合。把它减到两个。 “使用外部 jar(数据库)” 硬编码源中的一些数据。
-
1.确保所有更新仅在 EDT 中发生,2. 致电
invaildate、revalidate、repaint -
@Gianmarco 对我来说很好用:P - 我确实遇到的一个问题是窗口没有调整大小(正如我所期望的那样),这意味着某些按钮的布局区域为不可见的面板
标签: java swing validation layout repaint