JTextField 在静态时在某些页面上消失,而在其他页面上出现
JTextField disappears on some pages when being static, while appearing on others
在编写程序时,我将一些字段设为静态,即 JTextField
对应 E-Number
。但是现在这个字段的行为并不像预期的那样,在我的一些页面上它出现了,在其他一些页面上它消失了。
由于我在处理大量静力学方面不是很有经验,因此可能有一个我不理解的概念。
如果您想测试我的程序 (MCVE),我已经创建了一个非常简单但有效的示例。
它首先显示我的概览页面 - E-Number JTextField
丢失。
如果您单击搜索按钮,它会显示跟踪页面 - 显示 E-Number JTextField
。
两个页面包含 相同 workNumberPanel
,我找不到可以解释行为的差异。
那么,为什么 E-Number JTextField
出现在概览页面上,而跟踪页面上却不见了?感谢任何帮助/解释!
MainProgram.java
import java.awt.CardLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import net.miginfocom.swing.MigLayout;
public class MainProgram extends JFrame {
private static final long serialVersionUID = 1L;
public static JPanel centerPanel = new JPanel();
public static CardLayout contentCardsLayout = new CardLayout();
OverviewPage overviewPage = new OverviewPage();
TrackingPage trackingPage = new TrackingPage();
public void initialize() {
createCenterPanel();
}
private void createCenterPanel() {
centerPanel.setLayout(contentCardsLayout);
overviewPage.setName("overviewPage");
trackingPage.setName("trackingPage");
centerPanel.add(overviewPage, "overviewPage");
centerPanel.add(trackingPage, "trackingPage");
add(centerPanel, "growx, wrap");
}
public MainProgram() {
setBounds(300, 50, 1200, 900);
setLayout(new MigLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
MainProgram window = new MainProgram();
window.setVisible(true);
window.initialize();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
OverviewPage.java
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class OverviewPage extends JPanel {
WorkNumberPanel workNumberPanel = new WorkNumberPanel();
private static final long serialVersionUID = 1L;
public OverviewPage() {
setLayout(new MigLayout());
add(workNumberPanel, "wrap, growx");
}
}
TrackingPage.java
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class TrackingPage extends JPanel {
private static final long serialVersionUID = 1L;
WorkNumberPanel equipmentNumberPanel = new WorkNumberPanel();
public TrackingPage(){
setLayout(new MigLayout("", "grow, fill"));
add(equipmentNumberPanel, "wrap, growx");
}
}
WorkNumberPanel.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class WorkNumberPanel extends JPanel {
private static final long serialVersionUID = 1L;
private static final Integer TEXTFIELD_LENGTH = 20;
JPanel mainWorkNumberPanel = new JPanel();
JLabel lblWorkNumber = new JLabel("E-Nr: ");
JLabel lblN_Number = new JLabel("N-Nr.: ");
JLabel lblSNumber = new JLabel("W-Nr.: ");
public static JTextField txtWorkNumber = new JTextField(TEXTFIELD_LENGTH);
JTextField txtNNumber = new JTextField(TEXTFIELD_LENGTH);
JTextField txtSNumber = new JTextField(TEXTFIELD_LENGTH);
JButton btnSearchEntry = new JButton("Search");
public WorkNumberPanel() {
createEquipmentNumberPanel();
btnSearchEntry.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MainProgram.contentCardsLayout.show(MainProgram.centerPanel, "trackingPage");
}
});
}
private void createEquipmentNumberPanel() {
setLayout(new MigLayout());
mainWorkNumberPanel.setLayout(new MigLayout("", "[][grow, fill][][grow, fill][][grow, fill][]"));
mainWorkNumberPanel.add(lblWorkNumber);
mainWorkNumberPanel.add(txtWorkNumber);
mainWorkNumberPanel.add(lblN_Number);
mainWorkNumberPanel.add(txtNNumber);
mainWorkNumberPanel.add(lblSNumber);
mainWorkNumberPanel.add(txtSNumber);
mainWorkNumberPanel.add(btnSearchEntry);
add(mainWorkNumberPanel, "push, span, growx");
}
}
可能是因为当您使用此代码创建 "pages" 时
OverviewPage overviewPage = new OverviewPage();
TrackingPage trackingPage = new TrackingPage();
TrackingPage
将是最后一个执行以下行
mainWorkNumberPanel.add(txtWorkNumber);
在 private void createEquipmentNumberPanel()
中,因此该面板将 "own" JTextField。 UI 组件在任何给定时间只能在一个地方才有意义,否则事情会变得很奇怪:)
你的陈述
Both pages contain the same workNumberPanel and I cant find a difference, that would explain the behaviour.
根本不是真的。当您执行以下行
时,您正在 OverViewPage
和 TrackingPage
中创建一个新的 WorkNumberPanel
实例
WorkNumberPanel equipmentNumberPanel = new WorkNumberPanel();
所以我的建议是,您可以找到另一种实现所需内容的方法,而无需使用静态 JTextField(或任何其他 UI 组件)。
在这里你实例化了一个OverviewPage
,然后是一个TrackingPage
.
OverviewPage overviewPage = new OverviewPage();
TrackingPage trackingPage = new TrackingPage();
这两个 类 实例化一个 WorkNumberPanel
.
WorkNumberPanel
添加静态 JTextField
(txtWorkNumber) 到他们的显示面板 (mainWorkNumberPanel).
无法将单个 Component
添加到多个 Container
对象。
这就是您的文本字段所发生的情况,因为它是 static
而不是实例变量。
最后一次添加将获胜,因此文本字段将仅出现在 TrackingPage
中,而不再出现在 OverviewPage
中。
只是不要成功 static
。
首先你需要了解什么是静态字段。静态字段与对象的特定实例无关。该字段与 class 本身有关。
有很好的解释 here and here.
现在关于你的情况。 JComponent
一次只能添加到一个面板。将它添加到另一个会将其从第一个中删除。
在您的代码中,您正在创建 'WorkingNumberPanel' 的多个实例。执行此操作时,您将文本字段添加到面板,包括 static
文本字段 txtWorkNumber
。由于字段 txtWorkNumber
是静态的,因此您要将 同一对象 添加到多个组件,正如我上面提到的,这会将它从之前添加的任何地方删除。
解决此问题的一种可能方法是将 txtWorkNumber
中的值存储在静态变量中并创建一个新实例(非静态)文本字段以添加到面板。
在编写程序时,我将一些字段设为静态,即 JTextField
对应 E-Number
。但是现在这个字段的行为并不像预期的那样,在我的一些页面上它出现了,在其他一些页面上它消失了。
由于我在处理大量静力学方面不是很有经验,因此可能有一个我不理解的概念。
如果您想测试我的程序 (MCVE),我已经创建了一个非常简单但有效的示例。
它首先显示我的概览页面 - E-Number JTextField
丢失。
如果您单击搜索按钮,它会显示跟踪页面 - 显示 E-Number JTextField
。
两个页面包含 相同 workNumberPanel
,我找不到可以解释行为的差异。
那么,为什么 E-Number JTextField
出现在概览页面上,而跟踪页面上却不见了?感谢任何帮助/解释!
MainProgram.java
import java.awt.CardLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import net.miginfocom.swing.MigLayout;
public class MainProgram extends JFrame {
private static final long serialVersionUID = 1L;
public static JPanel centerPanel = new JPanel();
public static CardLayout contentCardsLayout = new CardLayout();
OverviewPage overviewPage = new OverviewPage();
TrackingPage trackingPage = new TrackingPage();
public void initialize() {
createCenterPanel();
}
private void createCenterPanel() {
centerPanel.setLayout(contentCardsLayout);
overviewPage.setName("overviewPage");
trackingPage.setName("trackingPage");
centerPanel.add(overviewPage, "overviewPage");
centerPanel.add(trackingPage, "trackingPage");
add(centerPanel, "growx, wrap");
}
public MainProgram() {
setBounds(300, 50, 1200, 900);
setLayout(new MigLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
MainProgram window = new MainProgram();
window.setVisible(true);
window.initialize();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
OverviewPage.java
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class OverviewPage extends JPanel {
WorkNumberPanel workNumberPanel = new WorkNumberPanel();
private static final long serialVersionUID = 1L;
public OverviewPage() {
setLayout(new MigLayout());
add(workNumberPanel, "wrap, growx");
}
}
TrackingPage.java
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class TrackingPage extends JPanel {
private static final long serialVersionUID = 1L;
WorkNumberPanel equipmentNumberPanel = new WorkNumberPanel();
public TrackingPage(){
setLayout(new MigLayout("", "grow, fill"));
add(equipmentNumberPanel, "wrap, growx");
}
}
WorkNumberPanel.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class WorkNumberPanel extends JPanel {
private static final long serialVersionUID = 1L;
private static final Integer TEXTFIELD_LENGTH = 20;
JPanel mainWorkNumberPanel = new JPanel();
JLabel lblWorkNumber = new JLabel("E-Nr: ");
JLabel lblN_Number = new JLabel("N-Nr.: ");
JLabel lblSNumber = new JLabel("W-Nr.: ");
public static JTextField txtWorkNumber = new JTextField(TEXTFIELD_LENGTH);
JTextField txtNNumber = new JTextField(TEXTFIELD_LENGTH);
JTextField txtSNumber = new JTextField(TEXTFIELD_LENGTH);
JButton btnSearchEntry = new JButton("Search");
public WorkNumberPanel() {
createEquipmentNumberPanel();
btnSearchEntry.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
MainProgram.contentCardsLayout.show(MainProgram.centerPanel, "trackingPage");
}
});
}
private void createEquipmentNumberPanel() {
setLayout(new MigLayout());
mainWorkNumberPanel.setLayout(new MigLayout("", "[][grow, fill][][grow, fill][][grow, fill][]"));
mainWorkNumberPanel.add(lblWorkNumber);
mainWorkNumberPanel.add(txtWorkNumber);
mainWorkNumberPanel.add(lblN_Number);
mainWorkNumberPanel.add(txtNNumber);
mainWorkNumberPanel.add(lblSNumber);
mainWorkNumberPanel.add(txtSNumber);
mainWorkNumberPanel.add(btnSearchEntry);
add(mainWorkNumberPanel, "push, span, growx");
}
}
可能是因为当您使用此代码创建 "pages" 时
OverviewPage overviewPage = new OverviewPage();
TrackingPage trackingPage = new TrackingPage();
TrackingPage
将是最后一个执行以下行
mainWorkNumberPanel.add(txtWorkNumber);
在 private void createEquipmentNumberPanel()
中,因此该面板将 "own" JTextField。 UI 组件在任何给定时间只能在一个地方才有意义,否则事情会变得很奇怪:)
你的陈述
Both pages contain the same workNumberPanel and I cant find a difference, that would explain the behaviour.
根本不是真的。当您执行以下行
时,您正在OverViewPage
和 TrackingPage
中创建一个新的 WorkNumberPanel
实例
WorkNumberPanel equipmentNumberPanel = new WorkNumberPanel();
所以我的建议是,您可以找到另一种实现所需内容的方法,而无需使用静态 JTextField(或任何其他 UI 组件)。
在这里你实例化了一个OverviewPage
,然后是一个TrackingPage
.
OverviewPage overviewPage = new OverviewPage();
TrackingPage trackingPage = new TrackingPage();
这两个 类 实例化一个 WorkNumberPanel
.
WorkNumberPanel
添加静态 JTextField
(txtWorkNumber) 到他们的显示面板 (mainWorkNumberPanel).
无法将单个 Component
添加到多个 Container
对象。
这就是您的文本字段所发生的情况,因为它是 static
而不是实例变量。
最后一次添加将获胜,因此文本字段将仅出现在 TrackingPage
中,而不再出现在 OverviewPage
中。
只是不要成功 static
。
首先你需要了解什么是静态字段。静态字段与对象的特定实例无关。该字段与 class 本身有关。
有很好的解释 here and here.
现在关于你的情况。 JComponent
一次只能添加到一个面板。将它添加到另一个会将其从第一个中删除。
在您的代码中,您正在创建 'WorkingNumberPanel' 的多个实例。执行此操作时,您将文本字段添加到面板,包括 static
文本字段 txtWorkNumber
。由于字段 txtWorkNumber
是静态的,因此您要将 同一对象 添加到多个组件,正如我上面提到的,这会将它从之前添加的任何地方删除。
解决此问题的一种可能方法是将 txtWorkNumber
中的值存储在静态变量中并创建一个新实例(非静态)文本字段以添加到面板。