将文本添加到另一个类的标签 - 简单逻辑问题

时间:2012-11-21 06:56:14

标签: java swing jframe jlabel

我在名为FrameTest的类中有一个标签和一个按钮,当我按下按钮时,一个名为buttonpressed的方法从类Test执行。在此buttonpressed方法中,我会将文本设置为FrameTest类中的标签。

我遇到的问题是,标签的文字没有设置。原因是我正在创建一个单独的对象来调用buttonpressed方法;

public void actionPerformed(ActionEvent arg0) {
                    Test t = new Test();
                    t.buttonpress();
                }

我正在Test类的main方法中创建一个单独的对象来创建UI。

public static void main(String[] args) {

         FrameTest f = new FrameTest();
         f.mainScreen();

    }

完整代码如下;

public class FrameTest extends JFrame {

private JPanel contentPane;
private JLabel lblLabel;
private FrameTest ft = this;

//private FrameTest frame;
/**
 * Launch the application.
 */
public  void mainScreen() {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                //FrameTest frame = new FrameTest();
                //setVisible(true);

                FrameTest frame = ft;
                frame.setVisible(true);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}


public void writeLabel(String k){
    this.lblLabel.setText(k);

}

public FrameTest() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setExtendedState(JFrame.MAXIMIZED_BOTH); 

    //setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    lblLabel = new JLabel("LABEL");
    contentPane.add(lblLabel, BorderLayout.CENTER);

    JButton btnNewButton = new JButton("Press");
    btnNewButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            Test t = new Test();
            t.buttonpress();
        }
    });
    contentPane.add(btnNewButton, BorderLayout.WEST);
    //pack();
    setLocationByPlatform(true);
}

}

测试类

public class Test {


public static void main(String[] args) {

     FrameTest f = new FrameTest();
     f.mainScreen();

}

public void buttonpress(){
     FrameTest f = new FrameTest();

     f.writeLabel("Button was pressed");

}

4 个答案:

答案 0 :(得分:3)

1)不要不必要地延长JFrame课程。

2)除非那是你想要的,否则不要使用setContentPane()。而只是简单地JFrame#add(..)

3)避开EventQueue并使用SwingUtilities阻止

4)在设置JFrame#pack();可见之前,不要忘记致电JFrame

5)Java命名约定是CamelCase,因此buttonPress()是正确的而不是buttonpress()

这是我做的一个例子(基本上你的代码是固定的):

Test.java:(这是将创建FrameTest实例的主要类,并具有更改JLabel文字的方法

import javax.swing.SwingUtilities;

public class Test {

    private static FrameTest f;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                f = new FrameTest();
                f.mainScreen();
            }
        });
    }

    void buttonPress() {
        f.writeLabel("Hello");
    }
}

FrameTest.java:(此类将显示JFrame并创建一个新的类Test实例来调用buttonPress()):

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class FrameTest {

    private JPanel panel;
    private JLabel lblLabel;
    private JFrame frame;

    private void initComponents() {
        frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);

        panel = new JPanel();
        panel.setBorder(new EmptyBorder(5, 5, 5, 5));
        panel.setLayout(new BorderLayout(0, 0));

        lblLabel = new JLabel("LABEL");
        panel.add(lblLabel, BorderLayout.CENTER);

        JButton btnNewButton = new JButton("Press");
        btnNewButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Test t = new Test();
                t.buttonPress();
            }
        });

        panel.add(btnNewButton, BorderLayout.WEST);

        frame.add(panel);

        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public void writeLabel(String k) {
        this.lblLabel.setText(k);
    }

    void mainScreen() {
        initComponents();
    }
}

答案 1 :(得分:1)

将FrameTest对象传递给buttonpress方法并在那里使用,而不是创建新对象:

public void buttonpress(FrameTest f) {
     f.writeLabel("Button was pressed");    
}

更改方法的调用,如下所示:

btnNewButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        Test t = new Test();
        t.buttonpress(FrameTest.this);
    }
});

你必须在这里使用FrameTest.this,因为你在一个实现ActionListener的匿名类中,所以普通this将引用该匿名类。

答案 2 :(得分:1)

- 第一种方法是使用Composition原则,在FrameTest.java中创建Test.java class实例然后使用此实例访问Label类中的FrameTest.java(在FrameTest中使用此标签的Getter Setters)。

- 第二种方法是肮脏且快速修复,在Label类中生成static FrameTest.java并直接设置Test.java的值}类。瞧它完成了.....

- 您的代码无效的原因,因为您创建了FrameTest class的一个非常新的实例。现在,您要么将FrameTest 对象引用变量传递给buttonpress()方法,要么label 静态

<强>例如

public class FrameTest extends JFrame {

private JPanel contentPane;
public static JLabel lblLabel;

.....

.....

}

public void buttonpress(FrameTest f) {
     f.writeLabel("Button was pressed");    
}

///////////////////////////编辑部分/////////////// ////////////////////

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

class FrameTest extends JFrame {

    private JPanel contentPane;
    private JLabel lblLabel;
    private FrameTest ft = this;

    public void mainScreen() {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {

                    FrameTest frame = ft;
                    frame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void writeLabel(String k) {
        this.lblLabel.setText(k);

    }

    public FrameTest() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setExtendedState(JFrame.MAXIMIZED_BOTH);

        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        lblLabel = new JLabel("LABEL");
        contentPane.add(lblLabel, BorderLayout.CENTER);

        JButton btnNewButton = new JButton("Press");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Test t = new Test();

                t.buttonpress(FrameTest.this); // Passing the current object to
                                                // the Test class
                                                // You can use just "this" , but
                                                // as we are in an Anonymous
                                                // Inner Class here,
                                                // we have to use
                                                // "Class_name.this"

            }
        });
        contentPane.add(btnNewButton, BorderLayout.WEST);
        // pack();
        setLocationByPlatform(true);
    }

}

public class Test {

    public static void main(String[] args) {

        FrameTest f = new FrameTest();
        f.mainScreen();

    }

    public void buttonpress(FrameTest f) { // Receiving the reference to the
                                            // current frame, but remember
                                            // THOUGH IT SEEMS that we are passing the
                                            // reference but still in
                                            //  Here and in Java its always pass
                                            // by copy.( ie pass by value).

        f.writeLabel("Button was pressed");

    }
}

答案 3 :(得分:0)

只需更改您的Test课程,如下所示

package com.test;

public class Test {

    private static FrameTest f;

    public static void main(String[] args) {

        f = new FrameTest();
        f.mainScreen();

    }

    public void buttonpress() {
        f.writeLabel("Button was pressed");
    }
}

实际问题是

  1. 您在main中创建了一个FrameTest变量f,并向用户显示了用户界面。
  2. 然后按下按钮再次创建了另一个FrameTest实例f,该实例未映射原始/第一f
  3. 现在我将变量视为一个类变量,它按预期工作