我的应用程序是使用Netbeans IDE(8.0.2)创建的。 我创建了一个JFrame,它包含一个绑定到数据库的JTable(使用JPA)。
我添加了一个"刷新"按钮,用于"刷新"直接来自数据库的JTable数据。
我想要"请等待"正在提取数据时显示的消息。
为此,我实现了一个扩展JDialog的JDialog_PleaseWait类。
由于一些奇怪的原因,虽然JDialog显示了它包含的jLabel没有显示...
JDialog_PleaseWait类是:
public class JDialog_PleaseWait extends javax.swing.JDialog {
//constructor for PleaseWait jDialogs
public JDialog_PleaseWait(String messageToDisplay){
initComponents();
this.jLabel_WaitMessage.setText(messageToDisplay);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jLabel_WaitMessage = new javax.swing.JLabel();
setTitle("Please wait...");
setAlwaysOnTop(true);
setBackground(new java.awt.Color(227, 248, 115));
setModalityType(java.awt.Dialog.ModalityType.MODELESS);
setResizable(false);
setType(java.awt.Window.Type.POPUP);
jLabel_WaitMessage.setBackground(new java.awt.Color(242, 253, 153));
jLabel_WaitMessage.setText("WaitMessage");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel_WaitMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 271, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel_WaitMessage)
);
pack();
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel_WaitMessage;
// End of variables declaration//GEN-END:variables
}
刷新JButton调用名为&#34; reload&#34;的方法。最初它必须显示jDialog并在之后执行其余任务。 更具体地说:
public void reload(){
jTable_Activities.setEnabled(false); // freezes the JTable
JDialog_PleaseWait pleaseWaitDialog = new JDialog_PleaseWait("Communicating with database server...."); // create a new PleaseWait JDialog
pleaseWaitDialog.pack();
pleaseWaitDialog.setLocationRelativeTo(this); //relative to this frame
pleaseWaitDialog.setVisible(true); //display the JDialog
.... ....
// runs a DB query and updates a JTable
.... ....
因此,出于某种原因,JDialog窗口会弹出但是jLabel没有显示...
我(我想)我和其他JDialogs做了(确切的?)同样的事情,但是由于一些奇怪的原因,这个JDialog无法正常工作......
任何提示?
答案 0 :(得分:3)
你可能的问题是你在Swing事件线程上获取你的数据(我没有看到你使用Thread / Runnable / SwingWorker之类的任何代码,因此我的假设),这是捆绑事件线程并阻止它做家务 - 包括将标签绘制到JDialog。解决方案:在后台线程中进行数据提取,例如使用SwingWorker。
这是一个展示我的意思的例子。代码创建两个JButton,一个显示JDialog 2秒,在此2秒内在Swing事件线程上运行Thread.sleep(...)
,另一个在后台线程中运行Thread.sleep(...)
。编译并运行代码以查看会发生什么。
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class PleaseWaitDialogTest extends JPanel {
protected static final long SLEEP_TIME = 2000L;
public PleaseWaitDialogTest() {
add(new JButton(new ShowWaitDialog("Without Thread", KeyEvent.VK_O, false)));
add(new JButton(new ShowWaitDialog("With BG Thread", KeyEvent.VK_W, true)));
}
private class ShowWaitDialog extends AbstractAction {
private boolean useBackgroundThread;
private JDialog dialog;
public ShowWaitDialog(String name, int mnemonic,
boolean useBackgroundThread) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.useBackgroundThread = useBackgroundThread;
}
@Override
public void actionPerformed(ActionEvent e) {
// create dialog in a lazy way
if (dialog == null) {
Window ancestorWindow = SwingUtilities
.getWindowAncestor(PleaseWaitDialogTest.this);
String title = "Dialog: " + getValue(NAME);
dialog = new JDialog(ancestorWindow, title,
ModalityType.MODELESS);
dialog.getContentPane().setLayout(new GridBagLayout());
dialog.add(new JLabel("Please Wait"));
dialog.setPreferredSize(new Dimension(250, 150));
dialog.pack();
dialog.setLocationByPlatform(true);
}
dialog.setVisible(true);
// since the dialog is non-modal, this code will run immediately after
// the dialog has been set visible
CloseRunnable closeRunnable = new CloseRunnable(dialog, SLEEP_TIME);
if (useBackgroundThread) {
// run the Runnable in a background thread
new Thread(closeRunnable).start();
} else {
// run the Runnable directly on the Swing event thread
closeRunnable.run();
}
}
}
private class CloseRunnable implements Runnable {
protected JDialog dialog;
private long sleepTime;
public CloseRunnable(JDialog dialog, long sleepTime) {
this.dialog = dialog;
this.sleepTime = sleepTime;
}
@Override
public void run() {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
// the dialog *must* be closed on the Swing event thread
SwingUtilities.invokeLater(new Runnable() {
public void run() {
if (dialog != null) {
dialog.setVisible(false);
}
}
});
}
}
private static void createAndShowGui() {
PleaseWaitDialogTest mainPanel = new PleaseWaitDialogTest();
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}