如何多次实例化 Java Class 的 Swing 组件
How to Instantiate Java Class of Swing Components Multiple Times
我有一个 java class 用作容器,它被编码为有一个 JPanel 和一个 TabbedPane
我有另一个 java class 构建一个 JPanel 包含 JLabels 和 [=25=我想要添加到容器 class 的 TabbedPane 的 ]JTextFields。我想要一个添加 JPanel 的 class 的新实例,这样我就可以向容器 class.
添加多个选项卡
我查看了以下内容: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,以及多位网络作者。我不是做作业的学生,我是一个老家伙,Java 的新手,正在将我的自上而下的技能转移到 OOP。
这是我的代码:
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
}
}
和
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);
}
}
不要使 JTabbedPane 静态化。此类 JComponentents 无法共享:例如,它们只有一个父 Container。
可以做一个容器class,比如JMyPanel,然后在几个地方创建多个实例。
如果这些实例也应该引用相同的数据模型,比如 JTextFields 更改相同的文本,并且两个实例都可以同时访问,那么在 swing 中需要更改这些文本字段上的侦听器。
这需要模型-视图-控制器范式。
可以制作一个单独的控制器 class 包含数据模型(文本为字符串),并让对 JTextField(视图)的更改调用控制器来更新模型并将更新的值移植到其他观看次数。
使用 Document:
jTextComponent.getDocument()
您可以让两个 JTextField 拥有自己的文档,并使用真实更改的相互通知。或者正如 Document 的 javadoc 建议使用一个共享文档。后者我记得很少使用,因为通常数据模型由更多输入组件组成。
(顺便说一句。在 JavaFX 中,TextField 将绑定到可以保存在数据模型中的 StringProperty,并通知更改并且可以绑定多次。)
LuxxMiner 在他的评论中是正确的.. MoreTabs 应该扩展 JPanel
然后,如果您想这样做,您可以添加多个 MoreTabs 实例。
您的代码还有其他几个主要问题:
1) 在 MoreTabs 中有几行:
panel.add(lblPutStuffOn);
panel.add(text);
随机出现在您 class 的顶部。你不能这样做,这将是一个编译错误。您应该在 MoreTabs class 中有一个构造函数来初始化您的变量。
构造函数:
public MoreTabs(String labelText){
lblPutStuffOn = new JLabel(labelText);
add(lblPutStuffOn);
add(text);
}
2) 这两行没有意义:
// add new JPanel to TabbedPane via a reusable Class
MoreTabs mt1 = new MoreTabs();
tabbedPane1.addTab( mt1() ); //non-static
看起来您要做的是实例化 MoreTabs 并将其作为选项卡添加到选项卡式面板。你不能只调用 mt1()。你需要像这样在它前面加上 'new' 前缀:
// 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);
请注意,我创建的构造函数接受一个字符串参数,该参数用于在选项卡中设置标签,当调用 new MoreTab("Some Label") 时,您将创建一个新的 MoreTab 实例并传入标签你要显示。
这是您修改后的代码,它可以运行并且基本上可以执行您想要的操作:
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
}
}
和
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);
}
}
我有一个 java class 用作容器,它被编码为有一个 JPanel 和一个 TabbedPane
我有另一个 java class 构建一个 JPanel 包含 JLabels 和 [=25=我想要添加到容器 class 的 TabbedPane 的 ]JTextFields。我想要一个添加 JPanel 的 class 的新实例,这样我就可以向容器 class.
添加多个选项卡我查看了以下内容: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,以及多位网络作者。我不是做作业的学生,我是一个老家伙,Java 的新手,正在将我的自上而下的技能转移到 OOP。
这是我的代码:
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
}
}
和
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);
}
}
不要使 JTabbedPane 静态化。此类 JComponentents 无法共享:例如,它们只有一个父 Container。
可以做一个容器class,比如JMyPanel,然后在几个地方创建多个实例。
如果这些实例也应该引用相同的数据模型,比如 JTextFields 更改相同的文本,并且两个实例都可以同时访问,那么在 swing 中需要更改这些文本字段上的侦听器。
这需要模型-视图-控制器范式。
可以制作一个单独的控制器 class 包含数据模型(文本为字符串),并让对 JTextField(视图)的更改调用控制器来更新模型并将更新的值移植到其他观看次数。
使用 Document:
jTextComponent.getDocument()
您可以让两个 JTextField 拥有自己的文档,并使用真实更改的相互通知。或者正如 Document 的 javadoc 建议使用一个共享文档。后者我记得很少使用,因为通常数据模型由更多输入组件组成。
(顺便说一句。在 JavaFX 中,TextField 将绑定到可以保存在数据模型中的 StringProperty,并通知更改并且可以绑定多次。)
LuxxMiner 在他的评论中是正确的.. MoreTabs 应该扩展 JPanel 然后,如果您想这样做,您可以添加多个 MoreTabs 实例。
您的代码还有其他几个主要问题:
1) 在 MoreTabs 中有几行:
panel.add(lblPutStuffOn);
panel.add(text);
随机出现在您 class 的顶部。你不能这样做,这将是一个编译错误。您应该在 MoreTabs class 中有一个构造函数来初始化您的变量。
构造函数:
public MoreTabs(String labelText){
lblPutStuffOn = new JLabel(labelText);
add(lblPutStuffOn);
add(text);
}
2) 这两行没有意义:
// add new JPanel to TabbedPane via a reusable Class
MoreTabs mt1 = new MoreTabs();
tabbedPane1.addTab( mt1() ); //non-static
看起来您要做的是实例化 MoreTabs 并将其作为选项卡添加到选项卡式面板。你不能只调用 mt1()。你需要像这样在它前面加上 'new' 前缀:
// 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);
请注意,我创建的构造函数接受一个字符串参数,该参数用于在选项卡中设置标签,当调用 new MoreTab("Some Label") 时,您将创建一个新的 MoreTab 实例并传入标签你要显示。
这是您修改后的代码,它可以运行并且基本上可以执行您想要的操作:
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
}
}
和
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);
}
}