简体   繁体   English

从Java中的另一个类将JLabel放在JScrollPane上

[英]Putting JLabel on JScrollPane from another class in Java

I am making family tree and this is my problem. 我正在做家谱,这是我的问题。 I have screens NewFamilyTree.java and NewPerson.java . 我有屏幕NewFamilyTree.javaNewPerson.java

NewFamilyTree.java: NewFamilyTree.java:

public class NewFamilyTree {
...
 private void initialize() {
    frame = new JFrame();
    frame.setTitle("New family tree");
    frame.setBounds(100, 100, 906, 569);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
...
    JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
    frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);

    JScrollPane scrollPane = new JScrollPane();
    tabbedPane.addTab("Tree", null, scrollPane, null);

    panel_1 = new JPanel();
    scrollPane.setViewportView(panel_1);
    panel_1.setLayout(new MigLayout("", "[][][][][][][][]", "[][][][][][]"));

NewPerson.java: NewPerson.java:

public class NewPerson{

...

buttonAdd = new JButton("Add");
        buttonAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                String names = textFieldNames.getText();
                String dateBirth = textFieldDateOfBirth.getText();
                String bio = textAreaBio.getText();

                Data newData = new Data(names, dateBirth, bio, fileID);

               //code that puts new label on scrollpane from NewFamilyTree.java
            }
        });
        buttonAdd.setBackground(new Color(30, 144, 255));
        frame.getContentPane().add(buttonAdd, "cell 2 6,grow");
    }

I need to put new JLabel from class NewPerson , by pressing on button Add , on the JScrollPane of NewFamilytree.java . 我需要通过按下NewFamilytree.javaJScrollPane上的Add按钮,从class NewPerson放置new JLabel Hope someone can help, I searched a lot and couldn't help myself. 希望有人能提供帮助,我进行了很多搜索,但也无济于事。

EDIT: After the answer from @mjr. 编辑:@mjr的答案后。

I added public JPanel panel_1; 我添加了public JPanel panel_1; in NewFamilyTree . NewFamilyTree In Add action performed I added: 在执行的Add操作中,我添加了:

JLabel lblHomer = new JLabel("Homer");
                lblHomer.setIcon(new ImageIcon("C:\\Users\\Tinmar\\Desktop\\HomerSimpson3.gif"));
                panel_1.add(lblHomer, "cell 7 5");

No errors, but - nothing happens after I press the add button. 没有错误,但是-按添加按钮后没有任何反应。 I also added NewPerson EXTENDS NewFamilyTree , ofc . 我还添加了NewPerson EXTENDS NewFamilyTreeofc

  1. NewPerson doesn't need extend from NewFamilyTree , it's not adding any functionality to the class NewPerson不需要从NewFamilyTree扩展,也不需要向NewFamilyTree添加任何功能
  2. Instead of using a JFrame in NewPerson , consider using a modal JDialog instead. 不要在NewPerson中使用JFrame ,而NewPerson考虑使用模式JDialog See How to Make Dialogs for more details 有关更多详细信息,请参见如何制作对话框
  3. Limit the exposure of components between classes. 限制类之间组件的暴露。 There is no reason why NewFamilyTree should be able to access the "window" been used by NewPerson . 没有理由为什么NewFamilyTree应该能够访问“窗口”使用过NewPerson There's no reason why NewPerson should be adding anything to NewFamilyTree NewPerson没有理由向NewFamilyTree添加任何NewFamilyTree
  4. Don't mix heavy weight components (like java.awt.Button ) with light weight components, this can cause no end of issues... 不要将重量级的组件(例如java.awt.Button )与重量轻的组件混合使用,这样就不会导致问题的终结。

You need to change the way you think of things. 您需要改变对事物的看法。 Instead of trying to make the NewPerson update the UI of the NewFamilyTree , have NewPerson gather the details from the user and pass this information back to NewFamilyTree so it can use it... 与其尝试使NewPerson更新NewPerson的UI, NewFamilyTreeNewPerson从用户NewPerson收集详细信息并将此信息传递回NewFamilyTree以便它可以使用...

For example... 例如...

JButton newPersonButton = new JButton("New Person");
newPersonButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        Data data = NewPerson.createPerson(frame);
        if (data != null) {
            JLabel lblHomer = new JLabel(data.names);
            panel_1.add(lblHomer, "cell 7 5");
            panel_1.revalidate();
        }
    }
});

This basically uses a static method createPerson which passes back a instance of Data (or null if the user cancelled the operation), which NewFamilyTree can then use. 这基本上使用static方法createPerson ,该方法将传递一个Data实例(如果用户取消了该操作,则NewFamilyTree null ),然后可以使用NewFamilyTree It decouples the code, as NewPerson is not relient on anything from NewFamilyTree and NewFamilyTree maintains control. 它解耦代码, NewPerson没有任何东西relient从NewFamilyTreeNewFamilyTree保持控制。 This clearly defines the areas of responsibility between the two classes, it also means that NewPerson could be called from anywhere... 这清楚地定义了两个类之间的职责范围,也意味着可以从任何地方调用NewPerson ...

The createPerson method looks, something like, this... createPerson方法看起来像这样...

public static Data createPerson(Component comp) {
    NewPerson newPerson = new NewPerson();
    Window win = SwingUtilities.getWindowAncestor(comp);
    JDialog dialog = null;
    if (win instanceof Frame) {
        dialog = new JDialog((Frame) win, "New person", true);
    } else if (win instanceof Dialog) {
        dialog = new JDialog((Dialog) win, "New person", true);
    } else {
        dialog = new JDialog((Frame) null, "New person", true);
    }
    newPerson.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();
            if (source instanceof Component) {
                Window win = SwingUtilities.getWindowAncestor((Component) source);
                win.dispose();
            }
        }
    });
    dialog.add(newPerson);
    dialog.setVisible(true);

    return newPerson.getData();
}

It basically creates and instance of JDialog , shows it to the user and waits until the NewPerson class triggers an ActionEvent , which it uses to dispose of the dialog. 它基本上创建JDialog实例,并将其显示给用户并等待,直到NewPerson类触发ActionEvent ,该事件用于处理对话框。 It then asks the instance of NewPerson for the data... 然后,它向NewPerson实例询问数据。

And because there's a whole bunch of functionality I've not talked about, here's a fully runnable example... 而且由于没有提到很多功能,因此这里有一个完全可运行的示例...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import net.miginfocom.swing.MigLayout;

public class NewFamilyTree {

    private JFrame frame;
    private JPanel panel_1;
    private JScrollPane scrollPane;
    private JTabbedPane tabbedPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    NewFamilyTree window = new NewFamilyTree();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        });
    }

    /**
     * Create the application.
     */
    public NewFamilyTree() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setTitle("New family tree");
        frame.getContentPane().setBackground(new Color(135, 206, 250));
        frame.setBounds(100, 100, 906, 569);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setBackground(new Color(30, 144, 255));
        frame.getContentPane().add(panel, BorderLayout.EAST);
        panel.setLayout(new MigLayout("", "[]", "[][][][][][][][]"));

        JButton newPersonButton = new JButton("New Person");
        newPersonButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                Data data = NewPerson.createPerson(frame);
                if (data != null) {
                    JLabel lblHomer = new JLabel(data.names);
//                    lblHomer.setIcon(new ImageIcon("C:\\Users\\Tinmar\\Desktop\\HomerSimpson3.gif"));
                    panel_1.add(lblHomer, "cell 7 5");
                    panel_1.revalidate();
                }
            }
        });
        panel.add(newPersonButton, "cell 0 5");

        JButton btnNewButton_1 = new JButton("New button");
        panel.add(btnNewButton_1, "cell 0 6");

        tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);

        scrollPane = new JScrollPane();
        tabbedPane.addTab("Tree", null, scrollPane, null);

        panel_1 = new JPanel();
        scrollPane.setViewportView(panel_1);
        panel_1.setLayout(new MigLayout("", "[][][][][][][][]", "[][][][][][]"));

//        JLabel lblHomer = new JLabel("Homer");
//        lblHomer.setIcon(new ImageIcon("C:\\Users\\Tinmar\\Desktop\\HomerSimpson3.gif"));
//        panel_1.add(lblHomer, "cell 7 5");
        JScrollPane scrollPane_1 = new JScrollPane();
        tabbedPane.addTab("Info", null, scrollPane_1, null);

        frame.repaint();

    }
//
//    /**
//     * Launch the application.
//     */
//    public static void main(String[] args) {
//        EventQueue.invokeLater(new Runnable() {
//            public void run() {
//                try {
//                    NewPerson window = new NewPerson();
//                    window.frame.setVisible(true);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        });
//    }

    public static class NewPerson extends JPanel {

        private JTextField textFieldNames;
        private JButton selectPictureButton;
        private JLabel labelDateOfBirth;
        private JTextField textFieldDateOfBirth;
        private JLabel labelShortBio;
        private JTextArea textAreaBio;
        private JLabel labelSelectPicture;
        private JButton buttonAdd;
        private String fileID;

        private Data data;

        /**
         * Create the application.
         */
        private NewPerson() {
            initialize();
        }

        public static Data createPerson(Component comp) {
            NewPerson newPerson = new NewPerson();
            Window win = SwingUtilities.getWindowAncestor(comp);
            JDialog dialog = null;
            if (win instanceof Frame) {
                dialog = new JDialog((Frame) win, "New person", true);
            } else if (win instanceof Dialog) {
                dialog = new JDialog((Dialog) win, "New person", true);
            } else {
                dialog = new JDialog((Frame) null, "New person", true);
            }
            newPerson.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Object source = e.getSource();
                    if (source instanceof Component) {
                        Window win = SwingUtilities.getWindowAncestor((Component) source);
                        win.dispose();
                    }
                }
            });
            dialog.add(newPerson);
            dialog.pack();
            dialog.setLocationRelativeTo(comp);
            dialog.setVisible(true);

            return newPerson.getData();
        }

        public void addActionListener(ActionListener listener) {
            listenerList.add(ActionListener.class, listener);
        }

        protected void fireActionPerformed() {
            ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
            if (listeners != null && listeners.length > 0) {
                ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "created");
                for (ActionListener listener : listeners) {
                    listener.actionPerformed(evt);
                }
            }
        }

        public Data getData() {
            return data;
        }

        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {
            setBackground(new Color(135, 206, 250));
            setLayout(new MigLayout("", "[][][grow]", "[][][][grow][][][]"));

            JLabel labelNames = new JLabel("Name and Surname:");
            add(labelNames, "cell 1 1,alignx trailing");

            textFieldNames = new JTextField();
            add(textFieldNames, "cell 2 1,growx");
            textFieldNames.setColumns(10);

            labelDateOfBirth = new JLabel("Date of birth:");
            add(labelDateOfBirth, "cell 1 2,alignx center,aligny center");

            textFieldDateOfBirth = new JTextField();
            add(textFieldDateOfBirth, "cell 2 2,growx");
            textFieldDateOfBirth.setColumns(10);

            labelShortBio = new JLabel("Bio:");
            add(labelShortBio, "cell 1 3,alignx center,aligny center");

            textAreaBio = new JTextArea();
            add(textAreaBio, "cell 2 3,grow");

            labelSelectPicture = new JLabel("Select picture:");
            add(labelSelectPicture, "cell 1 4,alignx center,aligny center");

            selectPictureButton = new JButton("...");
            selectPictureButton.setBackground(new Color(30, 144, 255));
            selectPictureButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {

                    JFileChooser chooser = new JFileChooser(new File(System.getProperty("user.home") + "\\Desktop"));

                    chooser.setDialogTitle("Select Location");
                    chooser.setFileSelectionMode(JFileChooser.APPROVE_OPTION);
                    chooser.setAcceptAllFileFilterUsed(false);

                    if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
                        fileID = chooser.getSelectedFile().getPath();
                        // txtField.setText(fileID);
                    }

                }
            });
            add(selectPictureButton, "cell 2 4");

            buttonAdd = new JButton("Add");
            buttonAdd.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {

                    String names = textFieldNames.getText();
                    String dateBirth = textFieldDateOfBirth.getText();
                    String bio = textAreaBio.getText();

                    data = new Data(names, dateBirth, bio, fileID);
                    fireActionPerformed();
                }
            });
            buttonAdd.setBackground(new Color(30, 144, 255));
            add(buttonAdd, "cell 2 6,grow");
        }

    }

    public static class Data {

        private final String names;
        private final String dateBirth;
        private final String bio;
        private final String fileID;

        private Data(String names, String dateBirth, String bio, String fileID) {
            this.names = names;
            this.dateBirth = dateBirth;
            this.bio = bio;
            this.fileID = fileID;
        }

    }

}
  • Don't rely on static to provide functionality across classes. 不要依靠static来提供跨类的功能。 If you HAVE to have something from another class, pass it as a reference. 如果您有其他课程的要求,请将其作为参考。 static is not your friend and you should be careful and wary of it's use static不是您的朋友,您应该小心并小心使用它
  • Don't expose the fields of your class without very good reason, rely on interface s to allow classes to provide or get information. 不要在没有充分理由的情况下公开类的字段,请依靠interface允许类提供或获取信息。 This limits what other classes can do. 这限制了其他类可以做什么。
  • Separate and isolate responsibility 分离和隔离责任
  • Take a look at How to Use Trees 看看如何使用树木

The same way that NewFamilyTree's frame is accessible in NewPerson when you add the button to it, the scrollPane must also be accessible in NewPerson, if you want to add a label from that class. 该NewFamilyTree的用同样的方法frame是NewPerson访问,当您添加的按钮,它的scrollPane也必须是可访问的NewPerson,如果你想从该类添加标签。 So just do the same thing with scrollPane as what you did with frame to be able to use it in NewPerson. 因此,只需使用scrollPane进行与使用frame即可在NewPerson中使用它。

I assumed that the JScrollPane and addButton are in different frames... although it will work for sure if they are in the same frame. 我假设JScrollPane和addButton在不同的框架中……尽管可以确定它们是否在同一框架中。 Basically you need to provide getters for the JScrollPane and the JPanel, so that they can be accessed from the NewPerson class. 基本上,您需要为JScrollPane和JPanel提供吸气剂,以便可以从NewPerson类访问它们。 In the action listener of the buttonAdd, you need to increase the preferred size of the panel,, if the labels don't feet in the current size of the panel. 在buttonAdd的动作侦听器中,如果标签不符合当前面板尺寸,则需要增加面板的首选尺寸。 The scrollbars will appear automatically when the preferred size of the panel are bigger that the view size of the JScrollPane. 当面板的首选大小大于JScrollPane的视图大小时,滚动条将自动出现。

Please see the code below: NewFamilyTree.jva: 请参见下面的代码:NewFamilyTree.jva:

package dva.test001;

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;

public class NewFamilyTree {
    private JFrame frame;
    private JScrollPane scrollPane;
    private JPanel panel;

    public NewFamilyTree() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.setTitle("New family tree");
        frame.setBounds(100, 100, 906, 569);
        frame.setLayout(new BorderLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
        panel = new JPanel();
        panel.setPreferredSize(new Dimension(700, 300));
        panel.setLayout(null);
        scrollPane = new JScrollPane(panel);
        tabbedPane.addTab("Tree", null, scrollPane, null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        NewFamilyTree ft = new NewFamilyTree();
        NewPerson np = new NewPerson(ft);
    }

    public JFrame getFrame() {
        return frame;
    }

    public JScrollPane getScrollPane() {
        return scrollPane;
    }

    public JPanel getPanel() {
        return panel;
    }
}

NewPerson.java: NewPerson.java:

package dva.test001;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class NewPerson {
    private NewFamilyTree familyTree;
    private static final int labelHeight = 30;

    public NewPerson(NewFamilyTree familyTree) {
        this.familyTree = familyTree;
        init();
    }

    public void init() {
        JFrame frame = new JFrame();
        frame.setTitle("New Person");
        frame.setBounds(100, 500, 906, 100);

        JButton buttonAdd = new JButton("Add");
        buttonAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                String names = "names"; //textFieldNames.getText();
                String dateBirth = "date"; //textFieldDateOfBirth.getText();
                String bio = "bio"; //textAreaBio.getText();

                //Data newData = new Data(names, dateBirth, bio, fileID);

               //code that puts new label on scrollpane from NewFamilyTree.java
                JLabel lbl = new JLabel(names);
                int top = familyTree.getPanel().getComponentCount() * labelHeight;
                if(top + labelHeight > familyTree.getPanel().getHeight()) {
                    familyTree.getPanel().setPreferredSize(new Dimension(familyTree.getPanel().getWidth(), top + labelHeight));
                    familyTree.getScrollPane().revalidate();
                }
                familyTree.getPanel().add(lbl);
                lbl.setBounds(10, top, 100, labelHeight);
            }
        });
        buttonAdd.setBackground(new Color(30, 144, 255));
        frame.getContentPane().add(buttonAdd);
        frame.setVisible(true);
    }
}

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

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