简体   繁体   English

Java Swing:获取对 GUI 组件的引用

[英]Java Swing: getting reference to GUI component

I have started to learn Java and thus Swing as well.我已经开始学习 Java 和 Swing。 I have been looking into building a GUI and wondering, how can I get the reference of GUI component to modify/read/delete it after I created it.我一直在研究构建一个 GUI,并想知道,在创建它之后如何获取 GUI 组件的引用来修改/读取/删除它。 Do I have to hold on to the reference I get when creating the component?在创建组件时我是否必须保留获得的参考? Or is there something like in Javascript: document.querySelector(), .querySelectorAll(), .getElementBy...() ?还是在 Javascript: document.querySelector(), .querySelectorAll(), .getElementBy...()中有类似的东西?

As an example we can use a button and a label.例如,我们可以使用一个按钮和一个 label。 When I click the button, I want to change the label.单击按钮时,我想更改 label。 Everyone in this example seems to just hold on to the reference they got when creating the components.此示例中的每个人似乎都只保留他们在创建组件时获得的引用。

I have read about MVC and so on, but that seems to me that it is even more advanced and more suitable for bigger apps.我读过 MVC 等等,但在我看来,它更先进,更适合更大的应用程序。

Could you please also point me in the right direction of learning Swing - reliable source of information - (there are tons of tutorials, but not all of them seem to be of sufficient quality).您能否也请您指出正确的学习方向 Swing - 可靠的信息来源 - (有大量教程,但并非所有教程似乎都具有足够的质量)。

Also I am aware that I will have to learn MVC at some point to create more sophisticated GUIs.我也知道我必须在某个时候学习 MVC 才能创建更复杂的 GUI。 So if you could share some reliable links on that topic I would also be very grateful.因此,如果您能分享一些关于该主题的可靠链接,我也将不胜感激。

Thank you.谢谢你。

JButton button = new JButton();
    button.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            //runs when button is pressed

            button pressed = (JButton)e.getSourse();
        }
        
    });

you can add a actionListener to a button and then get the button instance from the Event e您可以将 actionListener 添加到按钮,然后从 Event e 中获取按钮实例

JFrame f = new JFrame();
    f.setSize(500, 500);
    f.setVisible(true);
    
    JButton button = new JButton();
    button.setBounds(0, 0, 100, 100);
    f.add(button);
    
    button.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            System.out.println("pressed");
            JButton b = (JButton)e.getSource();
            b.setSize(200,200);
        }
        
    });

thats how I tested it, and it just works fine这就是我测试它的方式,它工作正常

As mentioned in the comments, an easy way of acquiring a reference to a desired component, is just to store the reference yourself.如评论中所述,获取对所需组件的引用的一种简单方法就是自己存储引用。 For your example where a button updates a label, you can maintain somewhere the reference to the label in your code.对于按钮更新 label 的示例,您可以在代码中的某处维护对 label 的引用。 For example:例如:

import java.awt.Font;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main {
    
    //Utility method to create a String with random contents:
    private static String randomString(final int length) {
        
        //Create the alphabet:
        String alphabet = "abcdefghijklmnopqrstuvwxyz";
        alphabet += alphabet.toUpperCase();
        alphabet += "0123456789";
        
        final int alphabetLength = alphabet.length();
        final Random rand = new Random();
        final char[] chars = new char[length];
        
        //Fill the random String:
        for (int i = 0; i < chars.length; ++i)
            chars[i] = alphabet.charAt(rand.nextInt(alphabetLength));
        
        return new String(chars);
    }
    
    private static void createAndShowGUI() {
        //Initialize a JLabel with a random text:
        final JLabel label = new JLabel(randomString(10));
        
        //Change font to MONOSPACED BOLD (of the current size):
        label.setFont(new Font(Font.MONOSPACED, Font.BOLD, label.getFont().getSize()));
        
        //Create the JButton:
        final JButton button = new JButton("Click to change label text");
        
        //See here we maintain a reference to the label in the lambda expression:
        button.addActionListener(event -> label.setText(randomString(10)));
        
        //Create a Container (JPanel is-a Container) for the button and the label:
        final JPanel contents = new JPanel(); //FlowLayout by default.
        contents.add(button);
        contents.add(label);
        
        final JFrame frame = new JFrame("Main");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Declares that the application will exit when we click the close icon of the frame.
        frame.getContentPane().add(contents);
        frame.pack(); //Adjust the size of the frame according to its contents.
        frame.setLocationRelativeTo(null); //Make the frame centered in screen.
        frame.setVisible(true); //Show the frame.
    }
    
    public static void main(final String[] args) {
        //Always call Swing related code on the EDT. On way to achieve this is by calling invokeLater like so:
        SwingUtilities.invokeLater(Main::createAndShowGUI); //Main::createAndShowGUI is just another lambda expression.
    }
}

The most reliable source of information for Swing, according to my knowledge, is the official turorial of Oracle in the following link: https://docs.oracle.com/javase/tutorial/uiswing/index.html which leads to many more links of tutorials about many topics on Swing. The most reliable source of information for Swing, according to my knowledge, is the official turorial of Oracle in the following link: https://docs.oracle.com/javase/tutorial/uiswing/index.html which leads to many more links关于 Swing 的许多主题的教程。

As for the helper methods to get a reference of a Component , Window , etc other than the current one, you can use the methods in SwingUtilities class, such as:至于获取Component引用的辅助方法, Window等,除了当前的,您可以使用SwingUtilities class 中的方法,例如:

  • getAncestorNamed : Every Component has-a name with corresponding accessor and mutator methods. getAncestorNamed :每个Component都有一个名称,带有相应的访问器修改器方法。 As such, you can get a refernce to a Component by name.因此,您可以通过名称获得对Component的引用。
  • getRoot : When you are creating Component s and adding the to Container s, and essentially Window s, you create a Component tree hierarchy. getRoot :当您创建Component并将其添加到Container时,本质上是Window ,您将创建一个Component树层次结构。 You can access the root Component of that hiearchy for any given Component via a call to this method.您可以通过调用此方法访问任何给定Component的该层次结构的根Component
  • getUnwrappedParent : Every Component belonging to a tree hierarchy of Component s has an ancestor (unless it is the root Component or a Component not belonging to any hierarchy yet). getUnwrappedParent :属于Component的树层次结构的每个Component都有一个祖先(除非它是根Component或尚不属于任何层次结构的Component )。 You can get its ancestor with this method.您可以使用此方法获取其祖先。
  • getWindowAncestor and windowForComponent : With those two equivalent methods, you can get the first Window ancestor of a Component (which in turn already belongs to a tree hierarchy of Component s). getWindowAncestorwindowForComponent :使用这两个等效方法,您可以获得Component的第一个Window祖先(它已经属于Component的树层次结构)。

But the most common case is that you will rarely use those methods (depending on your programming style) and usually maintain a reference, to all the Component s you need, in your class.但最常见的情况是您很少使用这些方法(取决于您的编程风格),并且通常会在 class 中维护对您需要的所有Component的引用。

Finally there are also some common methods for accessing all Component s of a Container such as getComponents which returns all the Component s inside a Container (and note here JFrame is-a Window which is-a Container ).最后,还有一些常用方法可以访问Container的所有Component ,例如getComponents ,它返回Container内的所有Component (注意这里的JFrame is-a Window is-a Container )。

The reverse operation (ie getting the parent Container on which a Component belongs to) is performed with getParent on a Component .使用Component上的getParent执行反向操作(即获取Component所属的父Container )。

Most of those methods are used after you add your Component s to the tree hierarchy.在您将Component添加到树层次结构后,将使用大多数这些方法。 For example there is not point in getting the window ancestor of a Component which is not added to any Window .例如,获取未添加到任何WindowComponent的 window 祖先是没有意义的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM