Jdialog中的组件未显示

时间:2015-09-26 11:58:35

标签: java swing components jdialog

我的应用程序是使用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无法正常工作......

任何提示?

1 个答案:

答案 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();
            }
        });
    }
}