消失的 JTextField 的摆动问题

Posted

技术标签:

【中文标题】消失的 JTextField 的摆动问题【英文标题】:Swing issue with disappearing JTextField 【发布时间】:2012-10-28 19:18:14 【问题描述】:

我在 NetBeans 中工作,尝试做我的项目,但遇到了一个问题。基本上,我正在构建一个数字计时器,毫秒显示为 7 个文本字段,以 8 的形状排列。

像这样:

   _
|     |
   _
|     |
   _

每毫秒我都会使某些文本字段不可见以显示不同的数字。比我有一个一秒的显示(当毫秒数到 10 时)显示秒,例如1, 2, 3 ...但由于某种原因,当毫秒达到 10 时,中间的文本字段会消失并且不再出现。我不知道是什么导致了这个问题。

这是我的代码:

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

/**
 *
 * 
 */
public class TimerFrame extends javax.swing.JFrame 

    /**
     * Creates new form TimerFrame
     */
    public TimerFrame() 
        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() 

        digitValue = new javax.swing.JTextField();
        jTextField1 = new javax.swing.JTextField();
        jTextField2 = new javax.swing.JTextField();
        jTextField3 = new javax.swing.JTextField();
        jTextField4 = new javax.swing.JTextField();
        jTextField5 = new javax.swing.JTextField();
        jTextField6 = new javax.swing.JTextField();
        jTextField7 = new javax.swing.JTextField();
        showDigit = new javax.swing.JButton();
        AddOne = new javax.swing.JButton();
        oneSecs = new javax.swing.JTextField();
        showOneSecs = new javax.swing.JButton();
        oneSecsDisplay = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Digital Timer");
        setBackground(new java.awt.Color(70, 70, 70));
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));

        digitValue.setText("000");

        jTextField1.setBackground(new java.awt.Color(255, 0, 0));
        jTextField1.setText("     ");

        jTextField2.setBackground(new java.awt.Color(255, 0, 0));
        jTextField2.setText("  ");

        jTextField3.setBackground(new java.awt.Color(255, 0, 0));
        jTextField3.setText("  ");

        jTextField4.setBackground(new java.awt.Color(255, 0, 0));
        jTextField4.setText("     ");

        jTextField5.setBackground(new java.awt.Color(255, 0, 0));
        jTextField5.setText("  ");

        jTextField6.setBackground(new java.awt.Color(255, 0, 0));
        jTextField6.setText("  ");
        jTextField6.addActionListener(new java.awt.event.ActionListener() 
            public void actionPerformed(java.awt.event.ActionEvent evt) 
                jTextField6ActionPerformed(evt);
            
        );

        jTextField7.setBackground(new java.awt.Color(255, 0, 0));
        jTextField7.setText("     ");

        showDigit.setText("Show the Digit");
        showDigit.addActionListener(new java.awt.event.ActionListener() 
            public void actionPerformed(java.awt.event.ActionEvent evt) 
                showDigitActionPerformed(evt);
            
        );

        AddOne.setText("Add One");
        AddOne.addActionListener(new java.awt.event.ActionListener() 
            public void actionPerformed(java.awt.event.ActionEvent evt) 
                AddOneActionPerformed(evt);
            
        );

        oneSecs.setText("0");

        showOneSecs.setText("Show One Secs");
        showOneSecs.addActionListener(new java.awt.event.ActionListener() 
            public void actionPerformed(java.awt.event.ActionEvent evt) 
                showOneSecsActionPerformed(evt);
            
        );

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(60, 60, 60)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(226, 226, 226)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(layout.createSequentialGroup()
                                .add(8, 8, 8)
                                .add(oneSecsDisplay, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 96, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .add(62, 62, 62)
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING, false)
                                        .add(layout.createSequentialGroup()
                                            .add(jTextField2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 13, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                            .add(jTextField3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 13, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                                        .add(layout.createSequentialGroup()
                                            .add(jTextField5, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 13, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                            .add(28, 28, 28)
                                            .add(jTextField6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 13, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                                    .add(layout.createSequentialGroup()
                                        .add(10, 10, 10)
                                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                            .add(jTextField7, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 34, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jTextField4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 34, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                                    .add(org.jdesktop.layout.GroupLayout.TRAILING, jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                                                .add(10, 10, 10))))))
                            .add(layout.createSequentialGroup()
                                .add(showOneSecs)
                                .add(6, 6, 6)
                                .add(AddOne)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(showDigit)
                                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                .add(digitValue, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                        .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .add(layout.createSequentialGroup()
                        .add(272, 272, 272)
                        .add(oneSecs, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(0, 0, Short.MAX_VALUE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                .addContainerGap(104, Short.MAX_VALUE)
                .add(oneSecs, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(oneSecsDisplay, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 120, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(layout.createSequentialGroup()
                        .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 13, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(jTextField3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(jTextField2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jTextField4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 13, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                            .add(jTextField6, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                            .add(jTextField5, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                        .add(7, 7, 7)
                        .add(jTextField7, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 13, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, showOneSecs)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                        .add(digitValue, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(showDigit)
                        .add(AddOne)))
                .addContainerGap())
        );

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

    private void jTextField6ActionPerformed(java.awt.event.ActionEvent evt) 
        // TODO add your handling code here:
    

    private void showDigitActionPerformed(java.awt.event.ActionEvent evt) 
        // showDigit
        int digit1 = Integer.parseInt(digitValue.getText());
        jTextField1.setVisible(true);
        jTextField2.setVisible(true);
        jTextField3.setVisible(true);
        jTextField4.setVisible(true);
        jTextField5.setVisible(true);
        jTextField6.setVisible(true);
        jTextField7.setVisible(true);
            if (digit1 == 0) 
                jTextField4.setVisible(false);
             else if (digit1 == 1) 
                jTextField1.setVisible(false);
                jTextField2.setVisible(false);
                jTextField4.setVisible(false);
                jTextField5.setVisible(false);
                jTextField7.setVisible(false);
             else if (digit1 == 2) 
                jTextField2.setVisible(false);
                jTextField6.setVisible(false);
             else if (digit1 == 3) 
                jTextField2.setVisible(false);
                jTextField5.setVisible(false);
             else if (digit1 == 4) 
                jTextField1.setVisible(false);
                jTextField5.setVisible(false);
                jTextField7.setVisible(false);
             else if (digit1 == 5) 
                jTextField3.setVisible(false);
                jTextField5.setVisible(false);
             else if (digit1 == 6) 
                jTextField3.setVisible(false);
             else if (digit1 == 7) 
                jTextField2.setVisible(false);
                jTextField4.setVisible(false);
                jTextField5.setVisible(false);
                jTextField7.setVisible(false);
             else if (digit1 == 9) 
                jTextField5.setVisible(false);
            
    

    private void AddOneActionPerformed(java.awt.event.ActionEvent evt) 
        // Add One
        int addOne = Integer.parseInt(digitValue.getText());
        addOne = addOne + 1;
        if (addOne == 10)  
            addOne = 0;
            int oneSecond = Integer.parseInt(oneSecs.getText());
            oneSecond = oneSecond + 1;
            String oneSeconds = Integer.toString(oneSecond);
            oneSecs.setText(oneSeconds);
            showOneSecsActionPerformed(evt);
        
        String myString = Integer.toString(addOne);
        digitValue.setText(myString);
        showDigitActionPerformed(evt);
    

    private void showOneSecsActionPerformed(java.awt.event.ActionEvent evt) 
        // Show One Secs
        int ones = Integer.parseInt(oneSecs.getText());
            if (ones == 0) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("0.jpg"));
             else if (ones == 1) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("1.jpg"));
             else if (ones == 2) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("2.jpg"));
             else if (ones == 3) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("3.jpg"));
             else if (ones == 4) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("4.jpg"));
             else if (ones == 5) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("5.jpg"));
             else if (ones == 6) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("6.jpg"));
             else if (ones == 7) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("7.jpg"));
             else if (ones == 8) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("8.jpg"));
             else if (ones == 9) 
                oneSecsDisplay.setIcon(new javax.swing.ImageIcon("9.jpg"));
            
    

    /**
     * @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(TimerFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
         catch (InstantiationException ex) 
            java.util.logging.Logger.getLogger(TimerFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
         catch (IllegalAccessException ex) 
            java.util.logging.Logger.getLogger(TimerFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
         catch (javax.swing.UnsupportedLookAndFeelException ex) 
            java.util.logging.Logger.getLogger(TimerFrame.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 TimerFrame().setVisible(true);
            
        );
    
    // Variables declaration - do not modify
    private javax.swing.JButton AddOne;
    private javax.swing.JTextField digitValue;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField3;
    private javax.swing.JTextField jTextField4;
    private javax.swing.JTextField jTextField5;
    private javax.swing.JTextField jTextField6;
    private javax.swing.JTextField jTextField7;
    private javax.swing.JTextField oneSecs;
    private javax.swing.JButton oneSecsDisplay;
    private javax.swing.JButton showDigit;
    private javax.swing.JButton showOneSecs;
    // End of variables declaration

【问题讨论】:

我冒昧地调整了标题和标签,因为这确实是一个 java Swing 问题。 你为什么使用 JTextFields?只需将构成 8 形状的条形绘制到 JPanel 的扩展上。 一秒有超过10毫秒(准确的说是1000)。 NetBeans 生成的代码! 整洁!我运行了您的代码,但看不到任何问题。你必须更清楚什么是错的。另外,正如其他人所说,在这里使用 JTextFields 很奇怪。你应该看看 Java 2D Graphics。 【参考方案1】:

正如 madth3 所指出的,一旦组件变得不可见,大多数布局管理器在计算布局时就不再考虑它。

虽然我可以想到 100 种不同的方法来解决这个问题,但下面的示例使用一个简单的 JPanel 作为一个段,并使用一个时髦的 alpha 颜色技巧来“隐藏”不影响现有布局的段.

public class Clock 

    public static void main(String[] args) 
        new Clock();
    

    public Clock() 
        EventQueue.invokeLater(new Runnable() 
            @Override
            public void run() 
                try 
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                 catch (ClassNotFoundException ex) 
                 catch (InstantiationException ex) 
                 catch (IllegalAccessException ex) 
                 catch (UnsupportedLookAndFeelException ex) 
                

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TimerPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            
        );
    

    public class TimerPane extends JPanel 

        private List<Segment> segments;
        private int tick = 0;

        public TimerPane() 
            setBorder(new EmptyBorder(9, 9, 9, 9));
            setLayout(new GridBagLayout());

            segments = new ArrayList<>(7);
            segments.add(new Segment(false));
            segments.add(new Segment(true));
            segments.add(new Segment(true));
            segments.add(new Segment(false));
            segments.add(new Segment(true));
            segments.add(new Segment(true));
            segments.add(new Segment(false));

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 1;
            gbc.gridy = 0;
            add(segments.get(0), gbc);
            gbc.gridx = 0;
            gbc.gridy++;
            add(segments.get(1), gbc);
            gbc.gridx = 2;
            add(segments.get(2), gbc);

            gbc.gridx = 1;
            gbc.gridy++;
            add(segments.get(3), gbc);
            gbc.gridy++;
            gbc.gridx = 0;
            add(segments.get(4), gbc);
            gbc.gridx = 2;
            add(segments.get(5), gbc);

            gbc.gridx = 1;
            gbc.gridy++;
            add(segments.get(6), gbc);

            Timer clock = new Timer(1000, new ActionListener() 
                @Override
                public void actionPerformed(ActionEvent e) 
                    List<Segment> active = new ArrayList<Segment>(segments);
                    switch (tick) 
                        case 0:
                            active.remove(segments.get(3));
                            break;
                        case 1:
                            active.remove(segments.get(0));
                            active.remove(segments.get(1));
                            active.remove(segments.get(3));
                            active.remove(segments.get(4));
                            active.remove(segments.get(6));
                            break;
                        case 2:
                            active.remove(segments.get(1));
                            active.remove(segments.get(5));
                            break;
                        case 3:
                            active.remove(segments.get(1));
                            active.remove(segments.get(4));
                            break;
                        case 4:
                            active.remove(segments.get(0));
                            active.remove(segments.get(4));
                            active.remove(segments.get(6));
                            break;
                        case 5:
                            active.remove(segments.get(2));
                            active.remove(segments.get(4));
                            break;
                        case 6:
                            active.remove(segments.get(2));
                            break;
                        case 7:
                            active.remove(segments.get(1));
                            active.remove(segments.get(3));
                            active.remove(segments.get(4));
                            active.remove(segments.get(6));
                            break;
                        case 8:
                            break;
                        case 9:
                            active.remove(segments.get(4));
                            active.remove(segments.get(6));
                            break;
                    

                    List<Segment> inactive = new ArrayList<>(segments);
                    inactive.removeAll(active);

                    color(active, true);
                    color(inactive, false);

                    tick++;
                    if (tick > 9) 
                        tick = 0;
                    

                    repaint();

                

                protected void color(List<Segment> segments, boolean isActive) 
                    for (Segment segment : segments) 
                        segment.setActive(isActive);
                    
                
            );
            clock.setInitialDelay(0);
            clock.setRepeats(true);
            clock.start();

        
    

    public class Segment extends JPanel 

        protected Color alpha = new Color(0, 0, 0, 0);

        private boolean vertical;
        private boolean active;

        public Segment(boolean vertical) 
            this.vertical = vertical;
            setActive(false);
        

        public void setActive(boolean value) 
            if (active != value) 
                active = value;
                if (active) 
                    setBackground(Color.LIGHT_GRAY);
                    setBorder(new LineBorder(Color.DARK_GRAY));
                 else 
                    setBackground(alpha);
                    setBorder(new LineBorder(alpha));
                
            
        

        public boolean isActive() 
            return active;
        

        @Override
        public Dimension getPreferredSize() 
            Dimension size = super.getPreferredSize();
            if (vertical) 
                size = new Dimension(5, 15);
             else 
                size = new Dimension(15, 5);
            
            return size;
        
    

【讨论】:

您好,谢谢您的回答,但我需要按照我提到的那样做,因为它是 uni 项目所必需的,我本可以采用这种不同且更有效的方式,但必须遵守规则;/ 因此,不要使用面板,而是用文本字段替换它们【参考方案2】:

对于初学者,我不得不说这是一个非常不寻常的数字显示实现。更改元素的可见性可能会导致组件重新布局并发生此类问题。

这个问题是由在按钮oneSecsDisplay 上更改图标的调用引起的,因为可以看到对showOneSecsActionPerformed 的调用注释掉了。布局重新打包了所有内容,中间的 JTextField 消失了。

我不是 GroupLayout 方面的专家,但一个可能的简短解决方案是将所有这些 TextFields 放入它自己的面板中。从长远来看,我同意@whiskeyspider 推荐a drawing alternative。

【讨论】:

以上是关于消失的 JTextField 的摆动问题的主要内容,如果未能解决你的问题,请参考以下文章

使用任何过滤器在数据库中搜索

添加时移除图像的组件

JText::_ 不工作

如何在 JTextField 中显示淡灰色的“重影文本”?

joomla 2.5 JText在xml文件中不起作用

有啥方法可以在运行时屏蔽进入 jText 区域的值,如果一直按下退格键,应该清除内容