我在使用几个按钮更新JPanel时出现问题。有时我需要删除或添加甚至修改一些按钮。我已经创建了一个例程,只需要很少的对话框和消息框。事实是,有时(随机)JPanel无法正确刷新(它不会按要求删除按钮,甚至不添加它)。如果我第二次调用刷新例程(我调用对话框添加一个按钮,然后单击exit而不添加任何东西)一切顺利。我不知道为什么,我认为这是关于时间和需要每个重绘或重新验证方法有效的时间,这个考虑是因为我试图调试程序(使用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;
}
这是用于获取用户插入的值的metod(使用自定义模式对话框)
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的其他部分也有同样的问题,比如comboBoxes或listBoxes,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();
}
}
答案 0 :(得分:1)
我觉得布局管理器存在问题......
就个人而言,我首先要使用不同的布局管理器。
默认情况下, JPanel
使用FlowLayout
,这有一个很棒的副作用,即不会“展开”组件扩展超出父容器的水平宽度。
虽然我了解Box
可以与其他布局管理器一起使用,但它可以与BoxLayout
一起使用,所以如果它不能按您想要的方式工作,我也不会感到惊讶。
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");
JPanel view = new JPanel(new GridBagLayout());
JScrollPane scroll = new JScrollPane(view);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
view.add(lbl, gbc);
// ########## SERVICES BUTTONS
for (int i = 0; i < s.size(); i++) {
JButton b = new JButton(s.get(i));
if (i % 3 == 0) {
gbc.gridy++;
gbc.gridx = 0;
} else {
gbc.gridx++;
}
view.add(b, gbc);
}
// ########## END SERVICES BUTTONS
view.add(Box.createVerticalGlue());
services.add(scroll);
services.revalidate();
services.repaint();
}
}
注意,我扔了JScrollPane
,可能不需要