スイングとボタンの少ない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;
}
削除、編集などの他の方法がいくつかありますが、問題(正しく更新されない)はこの方法のそれぞれでランダムに発生します。私が持っている最も単純な部分を投稿しました。
何か案が?(comboBoxesやlistBoxesなどのGUIの他の部分でも同じ問題があります。GUIはSwingUtilities.invokeLaterで開始されます)
ここにいくつかのSSCCEコードがあり、問題は次のように発生します:ADD、ADD、REMOVE、ADD
削除後の追加は正しく更新されません(私が言ったように、時々、時々ランダムに)。(他のものに触れることなく)。コードが十分に明確で短いことを願っています。関係していないように見えるデータベースを削除しました。
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();
}
}