自定义JPanels(Java Swing)的线程问题

时间:2014-10-28 03:54:12

标签: java swing thread-safety

对不起,如果您对最近的帖子感到恼火。如果我谷歌他们或使用API​​,我通常可以想象,但这个项目可能已经超出我的想象。我正在使用Swing创建一个简单的计算器,在IDE BlueJ中以LED格式显示(不提供任何宏)。

对不起,代码很长,但这是我正在显示的JFrame。

//Swing classes
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.Box;
import javax.swing.JTextField;
import javax.swing.JButton;

//Graphics classes
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.geom.AffineTransform;
import java.awt.Dimension;
import java.awt.event.*;
import java.awt.FlowLayout;

//Array, and math classes
import java.util.Arrays;
import java.util.ArrayList;
import java.lang.Math;

public class MCVE
{
public static void main(String[] args)
{
    SwingUtilities.invokeLater( new Runnable() {
            public void run() {

                //frame width and height
                final int FRAME_WIDTH = 317;
                final int FRAME_HEIGHT = 415;

                final JFrame myFrame = new JFrame();

                myFrame.setSize(FRAME_WIDTH,FRAME_HEIGHT);
                final JPanel myPanel = new JPanel();
                myPanel.setLayout(null);

                final JFrame ledFrame = new JFrame();
                ledFrame.setLayout(new FlowLayout());

                final MLED[] ledDisplay = new MLED[8];

                for(int i = 0; i < ledDisplay.length; i++)
                {

                    ledDisplay[i] = new MLED();

                }

                for(int i = 0; i < ledDisplay.length; i++)
                {

                    ledFrame.add(ledDisplay[i]);

                }

                //Buttons on Simple Calculator
                final JButton zeroButton = new JButton("0");
                zeroButton.setSize(50,50);
                zeroButton.setLocation(62,206);

                final JButton endButton = new JButton("End");
                endButton.setSize(102,50);
                endButton.setLocation(186,275);

                ledFrame.pack();
                ledFrame.setSize(480,170);
                ledFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                ledFrame.setLocationRelativeTo( null );
                ledFrame.setVisible( true );

                myFrame.add(myPanel);
                myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                myFrame.setVisible(true);

                myPanel.add(zeroButton);
                myPanel.add(endButton);

                ledFrame.pack();
                ledFrame.setSize(480,170);
                ledFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                ledFrame.setLocationRelativeTo( null );
                ledFrame.setVisible( true );
                class CalculatorListener implements ActionListener
                {
                    public void actionPerformed(ActionEvent e)
                    {

                        //The entry
                        int x=0;

                        //final answer
                        int finalAnswer = 0;

                        //the variable count has two uses: to give an index to store into the array storage and to signal to the program that the operation has been completed and that it is time to move into a new operation.
                        int count = 0;
                        int count2 = 6;


                        String tempString;

                        ArrayList<Character> toLedArray = new ArrayList<Character>();

                        if(e.getSource() == zeroButton)
                        {
                            if(count>1)
                            {
                                x = 0;
                                count = 0;
                            }
                            else
                            {
                                if(x!=0)
                                {
                                    x*=10;
                                    x+=0;
                                }
                                else
                                {
                                    x = 0;
                                }
                            }

                            tempString = String.valueOf(x);

                            for (char c : tempString.toCharArray()) {
                                toLedArray.add(c);
                            }

                            count = toLedArray.size();

                            if(count <= 8)
                            {
                                for(int i = 0; i < count ; i++)
                                {

                                    tempString += toLedArray.get(i); 
                                    System.out.println("Calculator:  0 Button: Count = " + count2);
                                    ledDisplay[count2].display(toLedArray.get(i));
                                    count2--;

                                }

                            }


                        }  
                        else if(e.getSource() == endButton)
                        {
                            myFrame.dispose();
                        }

                    }
                }

                //buttons are given life
                CalculatorListener myListener = new CalculatorListener();

                zeroButton.addActionListener(myListener);
                endButton.addActionListener(myListener);
            }
        });

}
}

这个类创建一个JFrame,它包含2个按钮,其中一个数字为零,另一个显示&#34; end&#34;。按下时的零按钮应该将最右边的7段显示器点亮为零的形状。不幸的是,这种情况并非如此。我怀疑从Swing操作中可能存在一些线程问题。

我希望你能看一下它,并在代码中指出我的逻辑错误。

以下是自定义JPanel和JButton

的两个类
public class MLED extends JPanel
{

// instance variables - replace the example below with your own
private static Bar[] bars = new Bar[7];

private GridBagConstraints c = new GridBagConstraints();
private final Dimension SIZE = new Dimension(60, 140);


/**
 * Constructor for objects of class LED
 */
public MLED()
{
    bars[0] = new MBar(30, 10);

    bars[1] = new MBar(10, 30);

    bars[2] = new MBar(10, 30);

    bars[3] = new MBar(30, 10);

    bars[4] = new MBar(10, 30);

    bars[5] = new MBar(10, 30);

    bars[6] = new Bar(30, 10);

    this.setLayout(new GridBagLayout());


    System.out.println("The LED class is being accessed");

}


public void display(char str)
{

    if(str == '0')
    {
            System.out.println("LED: The zero has been pressed");
            bars[0].lightUp();
            bars[1].lightUp();
            bars[2].lightUp();
            bars[4].lightUp();
            bars[5].lightUp();
            bars[6].lightUp();

    }




    repaint();
}

public void clear()
{
    bars[0].dim();
    bars[1].dim();
    bars[2].dim();
    bars[3].dim();
    bars[4].dim();
    bars[5].dim();
    bars[6].dim();
    bars[7].dim();

    repaint();
}

@Override public void paintComponent(Graphics g)
{
    super.paintComponent(g);

    for(int i = 0; i < bars.length; i++)
    {
        switch(i)
        {
            case 0:
                c.gridx = 1;
                c.gridy = 0;
                break;
            case 1:
                c.gridx = 0;
                c.gridy = 1;
                break;
            case 2:
                c.gridx = 2;
                c.gridy = 1;                
                break;
            case 3:
                c.gridx = 1;
                c.gridy = 2;
                break;
            case 4:
                c.gridx = 0;
                c.gridy = 3;    
                break;
            case 5:
                c.gridx = 2;
                c.gridy = 3;    
                break;
            case 6:
                c.gridx = 1;
                c.gridy = 4;  
                break;

        }
        this.add(bars[i], c);
    }

}


@Override public Dimension getPreferredSize()
{
    return SIZE;
}

}

自定义JComponent:

public class MBar extends JComponent
{
    // instance variables - replace the example below with your own
    private boolean litUp = false;
    private boolean vertical = false;
    private boolean rotated = false;
    private boolean rotClockwise = false;
    private int positionX;
    private int positionY;
    private final Dimension SIZE;



    public MBar(int sizeX, int sizeY)
    {
        litUp = false;
        //vertical = vert;
        SIZE = new Dimension(sizeX, sizeY);
        //positionX = posX;
        //positionY = posY;
        repaint();
    }

    public void lightUp()
    {
        litUp = true;
        repaint();
    }

    public void dim()
    {
        litUp = false;
        repaint();
    }

    public void setDirection(boolean vert)
    {
        vertical = vert;
        repaint();
    }

    public void rotate(boolean rot, boolean dir)
    {
        rotated = rot;
        rotClockwise = dir;
        repaint();
    }

    public void moveRight()
    {
        positionX = positionX + 11;
        repaint();
    }

    public void moveLeft()
    {
        positionX = positionX - 11;
        repaint();
    }

    @Override public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D)g;
        System.out.println("BAR: Paint Component");
        Color color;
        int sizeX;
        int sizeY;

        //         if(vertical == true)
        //         {
        //             sizeX = 10;
        //             sizeY = 30;
        if(rotated == true)
        {
            if(rotClockwise == true)
            {
                g2D.rotate(0.3398);
            }
            else
            {
                g2D.rotate(-0.3398);
            }
        }

        if(litUp == true)
        {
            color = Color.red;
        }
        else
        {
            color = Color.black;
        }

         //      else{
        //             sizeX = 30;
        //             sizeY = 10;
        //             if(litUp == true)
        //             {
        //                 color = Color.red;
        //             }
        //             else
        //             {
        //                 color = Color.black;
        //             }
        //         }
        g2D.setColor(color);
        g2D.fillRect(0 , 0, SIZE.width, SIZE.height);


    }

    @Override public Dimension getPreferredSize(){
        return SIZE;
    }



}

1 个答案:

答案 0 :(得分:1)

问题是private static Bar[] bars = new Bar[7];

您创建的每个MLED实例都使用自己的值对其进行重新初始化,这意味着MLED的每个实例实际上都获得了SAME引用,而不是它们应该拥有的引用。

当我制作private Bar[] bars = new Bar[7];时,它会产生......

enter image description here