GridLayout 内容未显示
GridLayout Contents not showing
我有一个 Jpanel
可以在两个视图中显示组件。网格视图和卡片视图。
卡片视图运行良好。 But when gridView is chosen the components are not displayed.
MCVE
SourceContainer.java
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box.Filler;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
public class SourceContainer extends JPanel implements ActionListener {
JPanel sourceMainPanel;
SourceCardPanel sourceCardPanel;
SourceGridPanel sourceGridPanel;
List<JComponent> components;
Boolean cardView = true;
public SourceContainer() {
init();
components = new ArrayList<>();
}
private void init() {
setLayout(new BorderLayout());
loadTitleComp();
loadBodyPanel();
}
private void loadTitleComp() {
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
toolBar.add(new Filler(new Dimension(35, 0), new Dimension(35, 0), new Dimension(10000, 10000)));
JLabel label = new JLabel("Source");
label.setFont(label.getFont().deriveFont(Font.BOLD, 14));
toolBar.add(label);
toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
JButton button = new JButton("Switch");
button.setActionCommand("SwitchView");
button.addActionListener(this);
toolBar.add(button);
add(toolBar, BorderLayout.NORTH);
}
private void loadBodyPanel() {
sourceMainPanel = new JPanel(new CardLayout());
sourceCardPanel = new SourceCardPanel();
sourceGridPanel = new SourceGridPanel();
sourceMainPanel.add(sourceCardPanel, "Card");
sourceMainPanel.add(sourceGridPanel, "Grid");
add(sourceMainPanel, BorderLayout.CENTER);
}
public void addSourceComp(String name, JComponent comp) {
JScrollPane scrollPane = new JScrollPane(comp);
scrollPane.setName(name);
components.add(scrollPane);
}
public void load() {
switchView();
}
@Override
public void actionPerformed(ActionEvent ae) {
switch (ae.getActionCommand()) {
case "SwitchView":
cardView = !cardView;
switchView();
break;
default:
throw new UnsupportedOperationException();
}
}
private void switchView() {
CardLayout layout = (CardLayout) sourceMainPanel.getLayout();
String cardName;
if (cardView) {
cardName = "Card";
sourceCardPanel.loadCards();
} else {
sourceGridPanel.loadGrid();
cardName = "Grid";
}
layout.show(sourceMainPanel, cardName);
}
class SourceCardPanel extends JPanel implements ActionListener {
JPanel sourcePanel;
CardLayout cardLayout;
JLabel sourceLabel;
public SourceCardPanel() {
setLayout(new BorderLayout());
cardLayout = new CardLayout();
sourcePanel = new JPanel(cardLayout);
sourceLabel = new JLabel("Soruce Project");
init();
}
private void init() {
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
JButton lbutton = new JButton("<<<");
// IconUtils.getIconByResourceName("goPrevious"));
lbutton.setActionCommand("GoToLeft");
lbutton.addActionListener(this);
toolBar.add(lbutton);
toolBar.add(sourceLabel);
JButton rbutton = new JButton(">>>");
// IconUtils.getIconByResourceName("goNext"));
rbutton.setActionCommand("GoToRight");
rbutton.addActionListener(this);
toolBar.add(rbutton);
toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
add(toolBar, BorderLayout.NORTH);
add(sourcePanel, BorderLayout.CENTER);
}
public void addCard(JComponent comp) {
sourcePanel.add(comp, comp.getName());
}
private JComponent getCurrentCard() {
for (Component comp : sourcePanel.getComponents()) {
if (comp.isVisible()) {
return (JComponent) comp;
}
}
return null;
}
public void loadCards() {
sourcePanel.removeAll();
for (JComponent component : components) {
addCard(component);
}
sourceLabel.setText(components.get(0).getName());
}
@Override
public void actionPerformed(ActionEvent ae) {
switch (ae.getActionCommand()) {
case "GoToLeft":
cardLayout.previous(sourcePanel);
break;
case "GoToRight":
cardLayout.next(sourcePanel);
break;
}
sourceLabel.setText(getCurrentCard().getName());
}
}
class SourceGridPanel extends JPanel {
JPanel gridpanel;
public SourceGridPanel() {
setLayout(new BorderLayout());
gridpanel = new JPanel(new GridLayout());
add(new JScrollPane(gridpanel), BorderLayout.CENTER);
}
public void loadGrid() {
gridpanel.removeAll();
for (int i = 0; i < components.size(); i++) {
create(components.get(i), i);
}
}
private void create(JComponent comp, int index) {
JPanel panel = new JPanel(new BorderLayout());
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
toolBar.add(new JLabel(comp.getName()));
panel.add(toolBar, BorderLayout.NORTH);
panel.add(comp, BorderLayout.CENTER);
gridpanel.add(panel, index);
}
}
}
Test.java
import java.awt.BorderLayout;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import merge.container.SourceContainer;
public class Test extends JFrame {
public Test() {
init();
}
private void init() {
SourceContainer sc = new SourceContainer();
for (int i = 0; i < 5; i++) {
sc.addSourceComp("Sample " + i, new JTree(new Object[]{i}));
}
sc.load();
add(sc, BorderLayout.CENTER);
}
public static void main(String[] args) {
setUpUI("Nimbus");
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Test samp = new Test();
samp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
samp.setTitle("Tree Test");
samp.setSize(600, 500);
samp.setLocationRelativeTo(null);
samp.setVisible(true);
}
});
}
private static void setUpUI(String ui) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if (ui.equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
在 loadGrid() 中将循环更改为:
for (int i = 0; i < components.size(); i++) {
create(components.get(i), i);
components.get(i).setVisible(true);
}
编辑: 我意识到我提供了一个解决方案,但实际上并没有提供完整的答案,所以为了完整起见:
CardLayout 通过修改其管理的组件的可见性一次显示 1 个组件。文档说明了这一点,尽管它并没有真正强调它(它在大多数文档中使用像“翻转”这样的术语):
https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html
Java 8 - CardLayout
Only one card is visible at a time, and the container acts as a stack of cards. The first component added to a CardLayout object is the visible component when the container is first displayed.
这是一个展示这种行为的例子:
public static void main(String[] args){
ArrayList<JComponent> components = new ArrayList<>();
components.add(new JPanel());
components.add(new JPanel());
components.add(new JPanel());
System.out.println("Component Visibility Prior to Card Layout:");
showVisibilityStatus(components);
JPanel cardPane = new JPanel(new CardLayout());
for (JComponent component : components){
cardPane.add(component);
}
System.out.println("\nComponent Visibility After Card Layout:");
showVisibilityStatus(components);
}
public static void showVisibilityStatus(ArrayList<JComponent> components){
for (JComponent component : components){
System.out.println(component.isVisible());
}
}
其控制台输出为:
Component Visibility Prior to Card Layout:
true
true
true
Component Visibility After Card Layout:
true
false
false
因此,当将使用 CardLayout 放置在面板中的组件移动到使用不同布局(例如 GridLayout)的另一个面板时,可能需要显式设置这些组件的可见性。
我过去在打包和显示所有内容后删除和添加组件时遇到过麻烦。重新加载循环中的组件后,您是否尝试过
gridpanel.revalidate();
gridpanel.repaint();
我有一个 Jpanel
可以在两个视图中显示组件。网格视图和卡片视图。
卡片视图运行良好。 But when gridView is chosen the components are not displayed.
MCVE
SourceContainer.java
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Box.Filler;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
public class SourceContainer extends JPanel implements ActionListener {
JPanel sourceMainPanel;
SourceCardPanel sourceCardPanel;
SourceGridPanel sourceGridPanel;
List<JComponent> components;
Boolean cardView = true;
public SourceContainer() {
init();
components = new ArrayList<>();
}
private void init() {
setLayout(new BorderLayout());
loadTitleComp();
loadBodyPanel();
}
private void loadTitleComp() {
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
toolBar.add(new Filler(new Dimension(35, 0), new Dimension(35, 0), new Dimension(10000, 10000)));
JLabel label = new JLabel("Source");
label.setFont(label.getFont().deriveFont(Font.BOLD, 14));
toolBar.add(label);
toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
JButton button = new JButton("Switch");
button.setActionCommand("SwitchView");
button.addActionListener(this);
toolBar.add(button);
add(toolBar, BorderLayout.NORTH);
}
private void loadBodyPanel() {
sourceMainPanel = new JPanel(new CardLayout());
sourceCardPanel = new SourceCardPanel();
sourceGridPanel = new SourceGridPanel();
sourceMainPanel.add(sourceCardPanel, "Card");
sourceMainPanel.add(sourceGridPanel, "Grid");
add(sourceMainPanel, BorderLayout.CENTER);
}
public void addSourceComp(String name, JComponent comp) {
JScrollPane scrollPane = new JScrollPane(comp);
scrollPane.setName(name);
components.add(scrollPane);
}
public void load() {
switchView();
}
@Override
public void actionPerformed(ActionEvent ae) {
switch (ae.getActionCommand()) {
case "SwitchView":
cardView = !cardView;
switchView();
break;
default:
throw new UnsupportedOperationException();
}
}
private void switchView() {
CardLayout layout = (CardLayout) sourceMainPanel.getLayout();
String cardName;
if (cardView) {
cardName = "Card";
sourceCardPanel.loadCards();
} else {
sourceGridPanel.loadGrid();
cardName = "Grid";
}
layout.show(sourceMainPanel, cardName);
}
class SourceCardPanel extends JPanel implements ActionListener {
JPanel sourcePanel;
CardLayout cardLayout;
JLabel sourceLabel;
public SourceCardPanel() {
setLayout(new BorderLayout());
cardLayout = new CardLayout();
sourcePanel = new JPanel(cardLayout);
sourceLabel = new JLabel("Soruce Project");
init();
}
private void init() {
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
JButton lbutton = new JButton("<<<");
// IconUtils.getIconByResourceName("goPrevious"));
lbutton.setActionCommand("GoToLeft");
lbutton.addActionListener(this);
toolBar.add(lbutton);
toolBar.add(sourceLabel);
JButton rbutton = new JButton(">>>");
// IconUtils.getIconByResourceName("goNext"));
rbutton.setActionCommand("GoToRight");
rbutton.addActionListener(this);
toolBar.add(rbutton);
toolBar.add(new Filler(new Dimension(), new Dimension(), new Dimension(10000, 10000)));
add(toolBar, BorderLayout.NORTH);
add(sourcePanel, BorderLayout.CENTER);
}
public void addCard(JComponent comp) {
sourcePanel.add(comp, comp.getName());
}
private JComponent getCurrentCard() {
for (Component comp : sourcePanel.getComponents()) {
if (comp.isVisible()) {
return (JComponent) comp;
}
}
return null;
}
public void loadCards() {
sourcePanel.removeAll();
for (JComponent component : components) {
addCard(component);
}
sourceLabel.setText(components.get(0).getName());
}
@Override
public void actionPerformed(ActionEvent ae) {
switch (ae.getActionCommand()) {
case "GoToLeft":
cardLayout.previous(sourcePanel);
break;
case "GoToRight":
cardLayout.next(sourcePanel);
break;
}
sourceLabel.setText(getCurrentCard().getName());
}
}
class SourceGridPanel extends JPanel {
JPanel gridpanel;
public SourceGridPanel() {
setLayout(new BorderLayout());
gridpanel = new JPanel(new GridLayout());
add(new JScrollPane(gridpanel), BorderLayout.CENTER);
}
public void loadGrid() {
gridpanel.removeAll();
for (int i = 0; i < components.size(); i++) {
create(components.get(i), i);
}
}
private void create(JComponent comp, int index) {
JPanel panel = new JPanel(new BorderLayout());
JToolBar toolBar = new JToolBar();
toolBar.setFloatable(false);
toolBar.add(new JLabel(comp.getName()));
panel.add(toolBar, BorderLayout.NORTH);
panel.add(comp, BorderLayout.CENTER);
gridpanel.add(panel, index);
}
}
}
Test.java
import java.awt.BorderLayout;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import merge.container.SourceContainer;
public class Test extends JFrame {
public Test() {
init();
}
private void init() {
SourceContainer sc = new SourceContainer();
for (int i = 0; i < 5; i++) {
sc.addSourceComp("Sample " + i, new JTree(new Object[]{i}));
}
sc.load();
add(sc, BorderLayout.CENTER);
}
public static void main(String[] args) {
setUpUI("Nimbus");
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
Test samp = new Test();
samp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
samp.setTitle("Tree Test");
samp.setSize(600, 500);
samp.setLocationRelativeTo(null);
samp.setVisible(true);
}
});
}
private static void setUpUI(String ui) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if (ui.equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
在 loadGrid() 中将循环更改为:
for (int i = 0; i < components.size(); i++) {
create(components.get(i), i);
components.get(i).setVisible(true);
}
编辑: 我意识到我提供了一个解决方案,但实际上并没有提供完整的答案,所以为了完整起见:
CardLayout 通过修改其管理的组件的可见性一次显示 1 个组件。文档说明了这一点,尽管它并没有真正强调它(它在大多数文档中使用像“翻转”这样的术语):
https://docs.oracle.com/javase/8/docs/api/java/awt/CardLayout.html
Java 8 - CardLayout
Only one card is visible at a time, and the container acts as a stack of cards. The first component added to a CardLayout object is the visible component when the container is first displayed.
这是一个展示这种行为的例子:
public static void main(String[] args){
ArrayList<JComponent> components = new ArrayList<>();
components.add(new JPanel());
components.add(new JPanel());
components.add(new JPanel());
System.out.println("Component Visibility Prior to Card Layout:");
showVisibilityStatus(components);
JPanel cardPane = new JPanel(new CardLayout());
for (JComponent component : components){
cardPane.add(component);
}
System.out.println("\nComponent Visibility After Card Layout:");
showVisibilityStatus(components);
}
public static void showVisibilityStatus(ArrayList<JComponent> components){
for (JComponent component : components){
System.out.println(component.isVisible());
}
}
其控制台输出为:
Component Visibility Prior to Card Layout:
true
true
true
Component Visibility After Card Layout:
true
false
false
因此,当将使用 CardLayout 放置在面板中的组件移动到使用不同布局(例如 GridLayout)的另一个面板时,可能需要显式设置这些组件的可见性。
我过去在打包和显示所有内容后删除和添加组件时遇到过麻烦。重新加载循环中的组件后,您是否尝试过
gridpanel.revalidate();
gridpanel.repaint();