0

我希望我不会用这个看起来很愚蠢但给我这个新手 Java 编码器带来很多麻烦的问题来打扰 stackoverflow 周围的所有 Java 大师。

在我的辩护中,我必须提到我正在为此进行谷歌搜索,但在我的水平上找不到任何可以解释我是否能够实现我想要实现的目标(以及最终如何实现)的东西。

我正在解析 xml 并以用户友好的图形形式显示它。我试图显示加载此 xml 的进度,以便用户知道会发生什么。

所以我用两个面板创建了一个简单的表单——一个在顶部填充整个工作空间,另一个在底部起到状态栏的作用。顶部还有一个简单的菜单栏,因此用户可以单击file -> load以加载文件。我在该file -> load菜单按钮的单击事件中加载我的文件。

因此,当用户单击时file -> load,会发生以下情况:

JLabel progress_label = new JLabel("0%");
this.status_bar.add(progress_label);
this.status_bar.revalidate();
//some code that loads my xml
//inside loading loop I try to do this:
progress_label.setText(some_formula_to_calculate_percentage);
this.status_bar.revalidate();
//finish loading xml file
this.status_bar.remove(progress_label);
this.status_bar.revalidate();

上面的代码工作正常 - 除了一个小细节。我认为 revalidate() 是在事件触发后执行的,因此在事件执行期间添加标签然后删除我实际上看不到任何效果。

这是我的问题 - 有没有办法从事件内部重新验证我的面板?

非常感谢您的任何建议。


编辑 - 根据建议,我准备了一些示例代码来解释我正在尝试做的事情。

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package javaapplication6;

import javax.swing.JLabel;
/**
 *
 * @author
 */
public class NewJFrame extends javax.swing.JFrame {

/**
 * Creates new form NewJFrame
 */
public NewJFrame() {
    initComponents();
}

/**
 * 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">                          
private void initComponents() {

    jPanel1 = new javax.swing.JPanel();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jPanel1.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            jPanel1MouseClicked(evt);
        }
    });

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 476, Short.MAX_VALUE)
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 358, Short.MAX_VALUE)
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
    );

    pack();
}// </editor-fold>                        

private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {                                     
    JLabel test_label = new JLabel("test");
    test_label.setBounds(1, 1, 100, 100);
    this.jPanel1.add(test_label);
    this.jPanel1.revalidate();
    this.jPanel1.repaint();
    try
    {
        System.in.read();
    }
    catch ( Exception e )
    {
    }
    this.jPanel1.remove(test_label);
    this.jPanel1.revalidate();
}                                    

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });
}
// Variables declaration - do not modify                     
private javax.swing.JPanel jPanel1;
// End of variables declaration                   
}
4

1 回答 1

2

我认为 revalidate() 是在事件触发后执行的,因此在事件执行期间添加标签然后删除我实际上看不到任何效果

听起来您的代码正在 EDT 上执行。所以你最终只能看到最终结果。

阅读有关并发的 Swing 教程。您可能希望使用 a SwingWorker,以便您长时间运行的代码在单独的线程上执行,然后发布可以在 EDT 上绘制的结果。

于 2013-04-30T23:41:57.387 回答