需要“非矩形卡布局面板”或“透明组件”

时间:2013-08-30 18:36:55

标签: java swing jpanel transparent cardlayout

我有一个新的要求来改变我的显示器。

目前我在面板上方有一排3个单选按钮,带有卡片布局。按钮CONTROL显示卡布局面板的卡。但这似乎浪费了宝贵的屏幕空间。

可以使用拥有它们的面板上的GridLayout(4,1)及其标题标签轻松地将按钮行转换为一列按钮。然后理论上可以将该面板放置在卡布局面板中显示的每张卡的左上角,并且每张卡的顶行可以向上移动到按钮面板的右侧,从而允许更多的空间用于来到下面。

但是这个包容模型应该是什么?在此变体中,按钮面板必须出现在每张卡上。谁拥有它?从逻辑上讲,它需要由所有这些所在的父面板拥有,但它不会显示在卡上,这将覆盖它 - 除非我能

  1. 在每张卡显示时添加按钮面板,这可能会很麻烦,可能会导致闪烁。
  2. 使每张卡片的左上角都是透明的,允许它显示其父牌所拥有的左上角按钮面板。但是我该怎么做呢?
  3. 其他解决方案?

    也许

    1. 有两个卡片布局面板由单选按钮控制。右上角包含按钮面板以及位于两者下方的下部组件。

3 个答案:

答案 0 :(得分:2)

听起来你可以使用JLayeredPane作为两者的父组件,包含单选按钮和卡片面板的面板。

JLayeredPane允许其子组件重叠,每个子组件属于一个层。

要指定图层,可以将整数常量传递给JLayeredPane的add(Component,Object)方法作为约束参数。整数常量在JLayeredPane类本身中定义。您可以将JLayeredPane.DEFAULT_LAYER用于卡面板,将JLayeredPane.PALETTE_LAYER用于单选按钮面板。

设置图层后,您仍然需要在x,y空间中正确放置两个面板。我建议用这样的东西覆盖JLayeredPane的doLayout()方法(尚未测试):

public void doLayout()
{
    cardPanel.setBounds( new Rectangle( getSize() ));
    radioButtonPanel.setBounds( new Rectangle( radtioButtonPanel.getPreferredSize() ));
}

答案 1 :(得分:1)

您可以使用OverlayLayout显示卡片面板左上方的控制面板。

image

答案 2 :(得分:1)

我会忘记透明度的想法。只需将选项作为列表放在卡面板的左侧(或右侧,上方/下方)。我绝对不会把控制面板放在CardPanel本身上。它应该在外面。

选择列表可以是无线电,按钮,或者在此示例中,可以增加项目的JList,而不会弄乱布局。例如:

/*
 * CardLayoutDemo.java
 */
import java.awt.*;

import javax.swing.*;
import javax.swing.event.*;

@SuppressWarnings("unchecked")
public class CardLayoutDemo implements Runnable
{
  final static String CARD1 = "Gray Panel";
  final static String CARD2 = "Blue Panel";
  final static String CARD3 = "Green Panel";

  JPanel cards;
  CardLayout cl;

  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new CardLayoutDemo());
  }

  public void run()
  {
    final JList jList = new JList(new String[]{CARD1, CARD2, CARD3});
    jList.setPrototypeCellValue("XXXXXXXXXXXX");
    jList.setVisibleRowCount(5);
    jList.setSelectedIndex(0);
    jList.addListSelectionListener(new ListSelectionListener()
    {
      @Override
      public void valueChanged(ListSelectionEvent e)
      {
        String name = jList.getSelectedValue().toString();
        cl.show(cards, name);
      }
    });

    JScrollPane scroll = new JScrollPane(jList);
    scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    Dimension dim = new Dimension(300, 300);

    JPanel card1 = new JPanel();
    card1.setBackground(Color.GRAY);
    card1.setPreferredSize(dim);

    JPanel card2 = new JPanel();
    card2.setBackground(Color.BLUE);
    card2.setPreferredSize(dim);

    JPanel card3 = new JPanel();
    card3.setBackground(Color.GREEN);
    card3.setPreferredSize(dim);

    cl = new CardLayout();
    cards = new JPanel(cl);
    cards.add(card1, CARD1);
    cards.add(card2, CARD2);
    cards.add(card3, CARD3);

    JFrame f = new JFrame("CardLayout Demo");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(scroll, BorderLayout.WEST);
    f.add(cards, BorderLayout.CENTER);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

如果您想要选择标签,只需创建一个包含JLabel和JScrollPane的“选择面板”(或使用您的按钮网格面板),并将其放在Borderlayout.WEST中(而不是添加JScrollPane)直接地)。

另外,请查看JTabbedPane作为替代方案。