简体   繁体   中英

How to Instantiate Java Class of Swing Components Multiple Times

I have a java class being used as a container, it is coded to have a JPanel and a TabbedPane

I have another java class that builds a JPanel containing JLabel s and JTextField s that I want added to the TabbedPane of the container class. I want a new instance of the class that adds the JPanel, so I can add multiple tabs to the container class.

I have reviewed the following: Can we reuse Java Swing application components in other instances of same application? , Multiple instances of model components in Java Swing? , Multiple instance of ONE JFrame , and multiple web authors. I am not a student doing an assignment, I am an old dude, new to Java, moving my top-down skills to OOP.

Here is my code:

import java.awt.EventQueue;

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

@SuppressWarnings("serial")
public class TestContainer extends JFrame {

private JPanel contentPane;
public static JTabbedPane tabbedPane1;

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

/**
 * Create the frame.
 */
public TestContainer() {

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JScrollPane scrollBasePane = new JScrollPane();
    scrollBasePane.setBounds(10, 11, 414, 239);
    contentPane.add(scrollBasePane);

    JPanel panelBase = new JPanel();
    scrollBasePane.setViewportView(panelBase);
    panelBase.setLayout(null);

    tabbedPane1 = new JTabbedPane(JTabbedPane.TOP);
    tabbedPane1.setBounds(10, 11, 392, 215);
    panelBase.add(tabbedPane1);

    // add new JPanel to TabbedPane via a reusable Class
    MoreTabs mt1 = new MoreTabs();

    tabbedPane1.addTab( mt1() ); //non-static
    }
 }

And

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MoreTabs{

private JPanel panel = new JPanel();
private JLabel lblPutStuffOn = new JLabel("Put stuff on this panel, T3-MoreTabs.");
private JTextField text = new JTextField();

panel.add(lblPutStuffOn);
panel.add(text);

public String getLblText() {
    String lblText;
    lblText = lblPutStuffOn.getText();
    return lblText;
}

public void setLblText(String s){
    lblPutStuffOn.setText(s);
}

public String getTxtText() {
    String txtText;
    txtText = text.getText();
    return txtText;
}

public void setTxtText(String s){
    text.setText(s);
  }

}

Do not make the JTabbedPane static. Such JComponentents cannot be shared: they have a single parent Container for instance.

One can make a container class, say JMyPanel, and create several instances at several places.

If those instances also should refer to the same data model, say the JTextFields alter the same text, and both instances are accessible at the same time, then in swing one needs change listeners on those text fields.

This calls for a Model-View-Controller paradigm.

One can make one separate controller class containing the data model (texts as String), and let changes to a JTextField (a view) call the controller to update the model and port the updated value to other views.

Use the Document :

jTextComponent.getDocument()

You can have two JTextFields having their own Document and use a reciproke notification of true changes. Or as the javadoc of Document suggests use one shared Document. The latter I remember using seldom, as in general the data model consists out of more input components.

(BTW. In JavaFX a TextField would be bound to a StringProperty which can be held in the data model, and notifies on changes and can be bound more than once.)

LuxxMiner is right in his comment.. MoreTabs should extend JPanel Then you can add multiple instances of MoreTabs if that's what you want to do.

There are a couple of other major issues with your code:

1) In MoreTabs you have lines:

panel.add(lblPutStuffOn);
panel.add(text);

randomly at the top of your class. You can't do this and it will be a compile error. You should have a constructor in the MoreTabs class to initialize your variables.

Constructor:

public MoreTabs(String labelText){
    lblPutStuffOn = new JLabel(labelText);
    add(lblPutStuffOn);
    add(text);
}

2) These two lines don't make sense:

// add new JPanel to TabbedPane via a reusable Class
MoreTabs mt1 = new MoreTabs();

tabbedPane1.addTab( mt1() ); //non-static

It looks like what you are trying to do is instantiate MoreTabs and add as a tab to the tabbed Panel. You cant just call mt1(). You need to prefix it with 'new' like this:

// add new JPanel to TabbedPane via a reusable Class
MoreTabs mt1 = new MoreTabs("Label 1");
MoreTabs mt2 = new MoreTabs("Label 2");
MoreTabs mt3 = new MoreTabs("Label 3");

tabbedPane1.addTab( "More Tabs 1", mt1);
tabbedPane1.addTab( "More Tabs 2", mt2);
tabbedPane1.addTab( "More Tabs 3", mt3);

Note that The constructor I created accepts a String parameter, which is used to set the label in the tab and when calling new MoreTab("Some Label") you will create a new MoreTab instance and pass in the label you want displayed.

Here is your code after modification, which runs and should do basically what you want:

import java.awt.EventQueue;

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

@SuppressWarnings("serial")
public class TestContainer extends JFrame {

private JPanel contentPane;
public static JTabbedPane tabbedPane1;

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

/**
 * Create the frame.
 */
public TestContainer() {

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JScrollPane scrollBasePane = new JScrollPane();
    scrollBasePane.setBounds(10, 11, 414, 239);
    contentPane.add(scrollBasePane);

    JPanel panelBase = new JPanel();
    scrollBasePane.setViewportView(panelBase);
    panelBase.setLayout(null);

    tabbedPane1 = new JTabbedPane(JTabbedPane.TOP);
    tabbedPane1.setBounds(10, 11, 392, 215);
    panelBase.add(tabbedPane1);

    // add new JPanel to TabbedPane via a reusable Class
    MoreTabs mt1 = new MoreTabs("Label 1");
    MoreTabs mt2 = new MoreTabs("Label 2");
    MoreTabs mt3 = new MoreTabs("Label 3");

    tabbedPane1.addTab( "More Tabs 1", mt1); //non-static
    tabbedPane1.addTab( "More Tabs 2", mt2); //non-static
    tabbedPane1.addTab( "More Tabs 3", mt3); //non-static
    }
}

And

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class MoreTabs extends JPanel{

private JLabel lblPutStuffOn;
private JTextField text = new JTextField();

public MoreTabs(String labelText){
    lblPutStuffOn = new JLabel(labelText);
    add(lblPutStuffOn);
    add(text);
}

public String getLblText() {
    return lblPutStuffOn.getText();
}

public void setLblText(String s){
    lblPutStuffOn.setText(s);
}

public String getTxtText() {
    return text.getText();
}

public void setTxtText(String s){
    text.setText(s);
  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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