如何在Java中设置另一个class的Layout?
How to set Layout with another class in Java?
我正在编写一个带有复杂 TabbedPane 的程序,其中包含很多元素。由于我在我的一个 classes 中达到了字节限制,我决定将 class 拆分为 Initialisation/Button 监听器和实际的 GridBagLayout。但是现在我无法让它工作。我的主要 Class 看起来像这样:
public class Main{
JFrame mainFrame = new JFrame("");
JTabbedPane tabpane = new JTabbedPane();
JPanel panelTab1 = new Tab1();
JScrollPane scrollTab2 = new JScrollPane(new Tab2());
JScrollPane scrollTab3 = new JScrollPane(new Tab3());
JPanel panelTab4 = new Tab4();
JMenuBar bar = new MenuBar();
public Main(){
tabpane.add("Tab1", panelTab1);
tabpane.add("Tab2", scrollTab2);
tabpane.add("Tab3", scrollTab3);
tabpane.add("Tab4", panelTab4);
mainFrame.getContentPane().add(tabpane);
mainFrame.setSize(1920,1080);
mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
mainFrame.setVisible(true);
mainFrame.validate();
mainFrame.setJMenuBar(bar);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new Main();
}
});
}}
Tab3 是罪魁祸首,所以这是我拆分的两个 classes。
public class Tab3 extends JPanel {
JPanel Annex = new JPanel();
//A Bunch of Labels and Buttons
.
.
.
public Tab3(){
//ActionListeners for the Buttons
this.setLayout(new BorderLayout());
this.add(Annex,BorderLayout.WEST);
this.add(Bsp,BorderLayout.EAST);
}}
所有的GridBagLayout在下面class:
public class Tab3Layout extends Tab3{
public Tab3Layout(){
Annex.setLayout(new GridBagLayout());
GridBagConstraints co1 = new GridBagConstraints();
co1.gridx = 0;
co1.gridy = 0;
co1.anchor = GridBagConstraints.FIRST_LINE_START;
co1.weighty = 1.0;
Annex.add(Annex1, co1);
//and so on...
}}
现在我的问题是,如何让它工作?现在如果我编译,Tab3 就是空的。如果一切都在一个 class 中,它就会完全按照我想要的方式工作,但代码太长了。在我看来,我在 Tab3 class 中遗漏了一行,但即使经过数小时的修补和搜索,我也不知道如何解决这个问题。我尝试的一切都产生了更多错误。
问题出在继承上。 Tab3Layout
有自己的 Annex
JPanel
(继承自 Tab3
),它正在修改和添加组件,而 Tab3
class 正在插入它的 Annex
,它是通过 new JPanel()
初始化的,你什么都不做。 Tab3Layout
class 甚至从未触及 Annex
面板,您初始化并添加到 Tab3
.
public class Tab3 extends JPanel {
JPanel Annex = new JPanel(); // <----- this, an empty JPanel
//A Bunch of Labels and Buttons
public Tab3(){
//ActionListeners for the Buttons
this.setLayout(new BorderLayout());
this.add(Annex,BorderLayout.WEST); // <----- is inserted here
this.add(Bsp,BorderLayout.EAST);
}}
如果您删除 new JPanel()
,您将得到一个错误,这将说明两个 class 都在 不同的 对象上工作,这恰好发生同名。你需要将你想要出现在Tab3
中的所有components/panels传递给Tab3Layout
进行修改,然后你可以稍后用getters
检索它们。另一种方法是创建 AnnexPanel
class,它本身将扩展 JPanel class。它会设置自己的布局、组件等,并能够直接添加。关注 Single Responsibility Principle would be best, if your classes grow in size. If it's 200+ lines of code, you should consider refactoring it. If you will allow your class to grow like 3000+ lines of code, you will have a bad time. Try to forsee where you can create new class/method in early stages of development. See KISS principle .
嗯..我会以不同的方式拆分它们。
我的 Tab3Layout class。 Annex panel是injected via constructor
,你可以给它设置一个setter
,但是记得在注入前不要调用createAnnex()
。反正编译器会让你记住的。
public final class Tab3Layout {
private JPanel Annex;
JPanel Annex1; //just to avoid compiler error
private GridBagLayout gridBagLayout;
private GridBagConstraints co1;
public Tab3Layout(JPanel Annex) {
this.Annex = Annex;
this.gridBagLayout = new GridBagLayout();
this.co1 = new GridBagConstraints();
}
public void createAnnex() {
this.Annex.setLayout(gridBagLayout);
this.co1.gridx = 0;
this.co1.gridy = 0;
this.co1.anchor = GridBagConstraints.FIRST_LINE_START;
this.co1.weighty = 1.0;
this.Annex.add(Annex1, co1);
}
public JPanel getAnnex() {
return this.Annex;
}
}
然后是 Tab3 class:
public class Tab3 extends JPanel {
JPanel Annex;
Tab3Layout tab3Layout;
public Tab3() {
super();
this.Annex = new JPanel();
this.tab3Layout = new Tab3Layout(Annex);
this.tab3Layout.createAnnex();
this.setLayout(new BorderLayout());
this.add(tab3Layout.getAnnex(), BorderLayout.WEST);
this.add(new JPanel(), BorderLayout.EAST);
}
}
看看我的 GridBagManager 存储库,它可以让您了解如何设置另一个 class 的布局。
您还可以使用 JPanel 扩展 Tab3Layout。并记得使用 GridBagConstraints 设置 anchor
和 fill
。
JPanel Annex = new JPanel();
GridBagConstraints co1 = new GridBagConstraints();
至
JPanel annexPanel = new JPanel();
GridBagConstraints gridBagConstraints = new GridBagConstraints();
我个人使用 gbc
作为 GridBagConstraints
对象,正如您将在我上面提到的我的回购协议中看到的那样。
编辑:
我认为您应该将您的实现分成几个较小的 classes。那将是专业的方法。重构你的代码。对于初学者,您可以让每个面板都有自己的 class 扩展 JPanel
(就像我建议的 AnnexPanel
class)。
Edit2:createAnnex()
可以returnJPanel类型,减少样板代码,调用如下:
this.add(Tab3Layout.createAnnex(), co1);
而不是
Tab3Layout.createAnnex();
this.add(Tab3Layout.getAnnex(), co1);
如果是单例,甚至可以将 createAnnex()
带入构造函数(假设 class 扩展 JPanel
)。
我正在编写一个带有复杂 TabbedPane 的程序,其中包含很多元素。由于我在我的一个 classes 中达到了字节限制,我决定将 class 拆分为 Initialisation/Button 监听器和实际的 GridBagLayout。但是现在我无法让它工作。我的主要 Class 看起来像这样:
public class Main{
JFrame mainFrame = new JFrame("");
JTabbedPane tabpane = new JTabbedPane();
JPanel panelTab1 = new Tab1();
JScrollPane scrollTab2 = new JScrollPane(new Tab2());
JScrollPane scrollTab3 = new JScrollPane(new Tab3());
JPanel panelTab4 = new Tab4();
JMenuBar bar = new MenuBar();
public Main(){
tabpane.add("Tab1", panelTab1);
tabpane.add("Tab2", scrollTab2);
tabpane.add("Tab3", scrollTab3);
tabpane.add("Tab4", panelTab4);
mainFrame.getContentPane().add(tabpane);
mainFrame.setSize(1920,1080);
mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
mainFrame.setVisible(true);
mainFrame.validate();
mainFrame.setJMenuBar(bar);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new Main();
}
});
}}
Tab3 是罪魁祸首,所以这是我拆分的两个 classes。
public class Tab3 extends JPanel {
JPanel Annex = new JPanel();
//A Bunch of Labels and Buttons
.
.
.
public Tab3(){
//ActionListeners for the Buttons
this.setLayout(new BorderLayout());
this.add(Annex,BorderLayout.WEST);
this.add(Bsp,BorderLayout.EAST);
}}
所有的GridBagLayout在下面class:
public class Tab3Layout extends Tab3{
public Tab3Layout(){
Annex.setLayout(new GridBagLayout());
GridBagConstraints co1 = new GridBagConstraints();
co1.gridx = 0;
co1.gridy = 0;
co1.anchor = GridBagConstraints.FIRST_LINE_START;
co1.weighty = 1.0;
Annex.add(Annex1, co1);
//and so on...
}}
现在我的问题是,如何让它工作?现在如果我编译,Tab3 就是空的。如果一切都在一个 class 中,它就会完全按照我想要的方式工作,但代码太长了。在我看来,我在 Tab3 class 中遗漏了一行,但即使经过数小时的修补和搜索,我也不知道如何解决这个问题。我尝试的一切都产生了更多错误。
问题出在继承上。 Tab3Layout
有自己的 Annex
JPanel
(继承自 Tab3
),它正在修改和添加组件,而 Tab3
class 正在插入它的 Annex
,它是通过 new JPanel()
初始化的,你什么都不做。 Tab3Layout
class 甚至从未触及 Annex
面板,您初始化并添加到 Tab3
.
public class Tab3 extends JPanel {
JPanel Annex = new JPanel(); // <----- this, an empty JPanel
//A Bunch of Labels and Buttons
public Tab3(){
//ActionListeners for the Buttons
this.setLayout(new BorderLayout());
this.add(Annex,BorderLayout.WEST); // <----- is inserted here
this.add(Bsp,BorderLayout.EAST);
}}
如果您删除 new JPanel()
,您将得到一个错误,这将说明两个 class 都在 不同的 对象上工作,这恰好发生同名。你需要将你想要出现在Tab3
中的所有components/panels传递给Tab3Layout
进行修改,然后你可以稍后用getters
检索它们。另一种方法是创建 AnnexPanel
class,它本身将扩展 JPanel class。它会设置自己的布局、组件等,并能够直接添加。关注 Single Responsibility Principle would be best, if your classes grow in size. If it's 200+ lines of code, you should consider refactoring it. If you will allow your class to grow like 3000+ lines of code, you will have a bad time. Try to forsee where you can create new class/method in early stages of development. See KISS principle .
嗯..我会以不同的方式拆分它们。
我的 Tab3Layout class。 Annex panel是injected via constructor
,你可以给它设置一个setter
,但是记得在注入前不要调用createAnnex()
。反正编译器会让你记住的。
public final class Tab3Layout {
private JPanel Annex;
JPanel Annex1; //just to avoid compiler error
private GridBagLayout gridBagLayout;
private GridBagConstraints co1;
public Tab3Layout(JPanel Annex) {
this.Annex = Annex;
this.gridBagLayout = new GridBagLayout();
this.co1 = new GridBagConstraints();
}
public void createAnnex() {
this.Annex.setLayout(gridBagLayout);
this.co1.gridx = 0;
this.co1.gridy = 0;
this.co1.anchor = GridBagConstraints.FIRST_LINE_START;
this.co1.weighty = 1.0;
this.Annex.add(Annex1, co1);
}
public JPanel getAnnex() {
return this.Annex;
}
}
然后是 Tab3 class:
public class Tab3 extends JPanel {
JPanel Annex;
Tab3Layout tab3Layout;
public Tab3() {
super();
this.Annex = new JPanel();
this.tab3Layout = new Tab3Layout(Annex);
this.tab3Layout.createAnnex();
this.setLayout(new BorderLayout());
this.add(tab3Layout.getAnnex(), BorderLayout.WEST);
this.add(new JPanel(), BorderLayout.EAST);
}
}
看看我的 GridBagManager 存储库,它可以让您了解如何设置另一个 class 的布局。
您还可以使用 JPanel 扩展 Tab3Layout。并记得使用 GridBagConstraints 设置 anchor
和 fill
。
JPanel Annex = new JPanel();
GridBagConstraints co1 = new GridBagConstraints();
至
JPanel annexPanel = new JPanel();
GridBagConstraints gridBagConstraints = new GridBagConstraints();
我个人使用 gbc
作为 GridBagConstraints
对象,正如您将在我上面提到的我的回购协议中看到的那样。
编辑:
我认为您应该将您的实现分成几个较小的 classes。那将是专业的方法。重构你的代码。对于初学者,您可以让每个面板都有自己的 class 扩展 JPanel
(就像我建议的 AnnexPanel
class)。
Edit2:createAnnex()
可以returnJPanel类型,减少样板代码,调用如下:
this.add(Tab3Layout.createAnnex(), co1);
而不是
Tab3Layout.createAnnex();
this.add(Tab3Layout.getAnnex(), co1);
如果是单例,甚至可以将 createAnnex()
带入构造函数(假设 class 扩展 JPanel
)。