Попытка показать JTable и JTabbedPane в одном и том же контейнере
Я пытаюсь создать JFrame для отображения данных, которые мои бета-тестеры должны отправить мне (эту часть я уже сделал), и JTabbedPane для диаграмм (для их использования). // Я надеюсь на то, что, игнорируя такие вещи, как внешний вид (и раскраска; мне было слишком лень, чтобы полностью раскрасить картинку), выглядело бы примерно так:
, // Мне нужно было бы использовать CardLayout для JComboBox для отображения другой таблицы и другого JTabbedPane для вновь выбранного режима; это означает две таблицы и две JTabbedPanes.
Я попытался сделать небольшой (чрезвычайно упрощенный!) Пример этой установки, JFrame только с (очень простым!) JTabbedPane и небольшим JTable. Этот пример работает, если я назначаю свой JPanel (в котором находятся оба компонента) BorderLayout, но как только я даю ему GridLayout (или GridBagLayout // тот самый Layout, который я в конечном итоге буду использовать), будет отображаться только последний компонент, независимо от того, что Я попробую! Почему это?
Если это помогло бы кому-либо (это могло бы, учитывая, насколько я новичок в этом), вот пример кода:
JPanelLayoutTest.java
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
public class JPanelLayoutTest extends JFrame {
private JPanel aPanel;
private JTabbedPane tabbedPane;
private JTable someTable;
public JPanelLayoutTest(String title) throws HeadlessException {
super(title);
aPanel = setupPanel();
}
private JPanel setupPanel()
{
GridBagLayout gridBag = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
//making the panel have two columns and one row
JPanel panel = new JPanel(gridBag);
//add someTable to top
someTable = new JTable(new SampleTableModel());
/*JPanel somePanel = new JPanel();
somePanel.add(new JScrollPane(someTable));*/
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridheight = 1;
constraints.gridwidth = 1;
gridBag.setConstraints(new JScrollPane(someTable), constraints);
add(new JScrollPane(someTable));
//add tabbedPane to bottom
tabbedPane = new JTabbedPane();
tabbedPane.addTab("some component", new JLabel("some text"));
/*JPanel someOtherPanel = new JPanel();
someOtherPanel.add(tabbedPane);*/
constraints.gridy = 1;
gridBag.setConstraints(tabbedPane, constraints);
add(tabbedPane);
//add(tabbedPane);
return panel;
}
public void turnOnWindow()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
//setSize(400,200);
pack();
}
public static void main(String[] args) {
JPanelLayoutTest frame = new JPanelLayoutTest("JPanel Layout Test");
frame.turnOnWindow();
}
}
//Pardon the indentation; I wish this forum had support for the [code][/code] tag
SampleTableModel.java
import javax.swing.table.AbstractTableModel;
public class SampleTableModel extends AbstractTableModel {
//declaring the static arrays that will be the data for the table
private final String[] columnNames = {"Account", "Full Name", "Balance"};
private final int[] acctNumbers = {1000443749, 190238420, 928355};
private final String[] fullNames = {"Mike Warren", "Jack Smith", "Sarah Brown"};
private final double[] acctBalances = {193.38, 289.28, 21034.29};
public SampleTableModel()
{
// I do nothing in here; there is no reason to.
}
@Override
public int getColumnCount() { return columnNames.length; }
@Override
public int getRowCount() { return acctNumbers.length; }
@Override
public Object getValueAt(int row, int column) {
switch (column)
{
case 0:
return new Integer(acctNumbers[row]);
case 1:
return fullNames[row];
case 2:
return new Double(acctBalances[row]);
default:
return null; //there should be no way the code would ever reach here
}
}
@Override
public String getColumnName(int index) { return columnNames[index]; }
//Again, forgive my horrible indentation near the end here...
}
2 ответа
Твоя проблема
При использовании GridBagLayout (и многих других макетов) вам нужно передать ограничения, которые вы хотите использовать для определенного компонента, иначе менеджер компоновки будет использовать его значения по умолчанию.
Например, вы делаете...
gridBag.setConstraints(new JScrollPane(someTable), constraints);
add(new JScrollPane(someTable));
Но компонент, который вы добавляете, не является компонентом, к которому вы применили ограничения. Вместо этого сделайте что-нибудь более похожее на...
add(new JScrollPane(someTable), constraints);
А (возможно) лучшее решение
Разбейте свой пользовательский интерфейс на разделы. Каждый раздел имеет свои уникальные требования (я вижу три раздела).
я вижу GridLayout
в качестве базового макета, на который вы хотите добавить три дополнительные панели, которые представляют три раздела вашего пользовательского интерфейса.
Это обычно называется составными макетами, когда вы строите серию макетов для получения окончательного результата.
Вместо:
private JPanel setupPanel()
{
GridBagLayout gridBag = new GridBagLayout();
GridBagConstraints constraints = new GridBagConstraints();
//making the panel have two columns and one row
JPanel panel = new JPanel(gridBag);
//add someTable to top
someTable = new JTable(new SampleTableModel());
/*JPanel somePanel = new JPanel();
somePanel.add(new JScrollPane(someTable));*/
constraints.gridx = 0;
constraints.gridy = 0;
constraints.gridheight = 1;
constraints.gridwidth = 1;
gridBag.setConstraints(new JScrollPane(someTable), constraints);
add(new JScrollPane(someTable));
//add tabbedPane to bottom
tabbedPane = new JTabbedPane();
tabbedPane.addTab("some component", new JLabel("some text"));
/*JPanel someOtherPanel = new JPanel();
someOtherPanel.add(tabbedPane);*/
constraints.gridy = 1;
gridBag.setConstraints(tabbedPane, constraints);
add(tabbedPane);
//add(tabbedPane);
return panel;
}
Я думаю, вам повезет, если вы создадите свою панель в качестве расширения для JPanel: РЕДАКТИРОВАТЬ: Забыл упомянуть, что этот код можно многократно использовать и позволяет передавать другие объекты в JPanel... сэкономив вам массу работы позволяет перегружать конструкторы для разных сценариев.
//You can call new objects such as:
new MyPanel(data, otherComponent);
public class MyPanel extends JPanel{
String data;
public MyPanel(String someData, SomeOtherClass aClass){
this.data = someData;
setLayout(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
JPanel panel = new JPanel(gridBag);
//New addition
constraints.gridx = 0;
constraints.gridy = 0;
//add components to the JPanel with your grid (constraints)
add(new JScrollPane(someTable), constraints)
//New addition
constraints.gridx = 0;
constraints.gridy = 1;
//add components to the JPanel with your grid (constraints)
add(tabbedPane , constraints);
}
public String getData(){
return this.data;
}
}
Это следует паттерну MVC (который я рекомендую изучить, если вы планируете разрабатывать больше свингов). Я знаю, это действительно помогло мне!