【问题标题】:Transparency issue with overlay panel覆盖面板的透明度问题
【发布时间】:2011-04-11 09:43:27
【问题描述】:

我最初在 MigLayout 论坛上发布了这个问题,因为它在某种程度上是特定于 Layout Manager 的,我想说。不幸的是,现在已经一周了,根本没有任何 cmets,因此我想在这里重新发布这个问题,希望它不会被视为 X 发布。

好吧,我有以下问题: 一般来说,我想“灰色”一些内容(更准确地说是 JPanel 的内容)。我几乎设法通过将另一个JPanel“流动”在所需区域上以透明颜色来实现所需的效果。但是还有一个大问题: 一旦我将覆盖面板设置为可见,下面的组件将不会立即正确绘制。相反,它们最初会涂上一些白色,直到例如我最小化并重新最大化框架,这将导致正确绘制透明效果。

作为示例,我附上了“越野车”外观的屏幕截图。注意具有白色外观的单选按钮和复选框。另外我附上了代码来重现效果。目前我正在使用 Java 1.5 处理 Windows 7、32 位。 (Java 1.6 没有任何区别)。

我玩了很多不同的paint()/repaint()/(in/re)validate()/等。方法。将覆盖面板设置为可见后,没有任何效果可以正确绘制覆盖面板。

有什么想法吗?

BR,克里斯

EDIT1:关于代码示例 - 如果您运行它,您必须单击“检查”按钮来触发覆盖面板。 :) 我注意到的另一件事是外观问题因使用的 UI L&F 而异。在我的情况下,我使用过一次 Windows 和一次原生 Java UI(它被称为金属吗?),它们显示了不同的结果,即使它们都不能正常工作:P

错误截图链接:Screenshot

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import net.miginfocom.swing.MigLayout;

public class MigTest {
  public static void main(String[] args) {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.add(new TestLayeredPane());
    f.pack();
    f.setVisible(true);
  }
  public static class TestLayeredPane extends JPanel {
    private JPanel pnl_overlay_;

public TestLayeredPane() {
  super();
  this.setLayout(new MigLayout("fill, wrap 2", "", ""));

  initLayout();
}
private void initLayout() {
  JPanel pnl_direction = new JPanel(new MigLayout("wrap 3", "", ""));
  JPanel pnl_settings = new JPanel(new MigLayout("wrap 1", "", ""));
  JPanel pnl_input = new JPanel(new MigLayout("wrap 3", "", ""));

  JLabel lbl_ask_for = new JLabel();
  JLabel lbl_translation = new JLabel();

  ButtonGroup btn_group_ = new ButtonGroup();
  JRadioButton radiobtn_ask_lang1_ = new JRadioButton();
  JRadioButton radiobtn_ask_lang2_ = new JRadioButton();
  JRadioButton radiobtn_ask_random_ = new JRadioButton();

  JCheckBox chkbox_loop_ = new JCheckBox();
  JCheckBox chkbox_repeat_false_ = new JCheckBox();
  JCheckBox chkbox_letter_count_ = new JCheckBox();
  JCheckBox chkbox_ask_all_ = new JCheckBox();

  JLabel lbl_progress_ = new JLabel();
  JLabel lbl_question_ = new JLabel();

  JButton btn_check_ = new JButton();
  JButton btn_push_back_ = new JButton();

  JTextField tfield_answer_ = new JTextField();

  /** Customize all elements of our layout **/
  lbl_ask_for.setText("Ask for:");

  lbl_translation.setText("translation");

  radiobtn_ask_lang1_.setText("1st language");
  radiobtn_ask_lang2_.setText("2nd language");
  radiobtn_ask_random_.setText("Random language");

  btn_group_.add(radiobtn_ask_lang1_);
  btn_group_.add(radiobtn_ask_lang2_);
  btn_group_.add(radiobtn_ask_random_);

  chkbox_loop_.setText("Loop");
  chkbox_repeat_false_.setText("Repeat false answers");
  chkbox_letter_count_.setText("Show letter count");
  chkbox_ask_all_.setText("Ask for 1st and 2nd language");

  btn_check_.setText("Check");
  btn_check_.addActionListener(new ActionListener() {

    public void actionPerformed(ActionEvent e) {
      finishTraining();
    }
  });

  btn_push_back_.setText(" Push back");

  /** Add all elements to this panel **/
  pnl_direction.add(lbl_ask_for, "span 1 3");
  pnl_direction.add(radiobtn_ask_lang1_);
  pnl_direction.add(lbl_translation, "span 1 3");
  pnl_direction.add(radiobtn_ask_lang2_);
  pnl_direction.add(radiobtn_ask_random_);

  pnl_settings.add(chkbox_loop_);
  pnl_settings.add(chkbox_repeat_false_);
  pnl_settings.add(chkbox_letter_count_);
  pnl_settings.add(chkbox_ask_all_);

  pnl_input.add(lbl_question_, "align center");
  pnl_input.add(lbl_progress_, "span 2, align center");
  pnl_input.add(tfield_answer_, "span 1 2, align center, w 200!");
  pnl_input.add(btn_check_, "growy");
  pnl_input.add(btn_push_back_);

  pnl_overlay_ = new JPanel(new MigLayout("fill", "", ""));
  pnl_overlay_.setBackground(new Color(127, 127, 127, 100));
  this.add(pnl_overlay_, "pos (0%+2px) (0%+2px) (100%-2px) (100%-2px) ");
  pnl_overlay_.setVisible(false);

  this.add(pnl_direction, "gapbefore push");
  this.add(pnl_settings, "gapafter push");
  this.add(pnl_input, "span 2, gapbefore push, gapafter push");
}

private void finishTraining() {
  //disable all visible items in the content area
  for (Component comp : this.getComponents()) {

    if (comp instanceof JPanel) {
      for (Component comp2 : ((JPanel) comp).getComponents()) {
        comp2.setEnabled(false);
      }
    }
    else {
      comp.setEnabled(false);
    }
  }
  pnl_overlay_.setVisible(true);
}
  }
}

【问题讨论】:

  • 大家好......这个问题现在差不多两年了。加油!
  • 我才刚刚开始盗取一个合适的类:JLayersPanel,它将继承自 JPanel。该模型将使用 JLayeredPane 代码作为模板。欢迎提出建议,因为这对我要创建的设计至关重要。

标签: java swing miglayout


【解决方案1】:

在没有尝试调试您的代码的情况下,我快速搜索了有关禁用容器及其子项的主题。基本上有两种方法涉及递归地遍历子控件并禁用它们,或者像您正在做的那样覆盖禁用面板。

如果您不必跟踪所有子容器的先前启用状态并在要重新启用父容器时恢复它们,则递归选项很简单。像这样的函数可以做到:

static void setChildrenEnabled(Container root, boolean enable)
{
    Component children[] = root.getComponents();
    for(int i = 0; i < children.length; i++)
    {
        children[i].setEnabled(enable);
        if(children[i] instanceof Container)
        {
            setChildrenEnabled((Container) children[i], enable);
        }          
    }
}

对于像您这样的方法,我发现似乎是一篇不错的帖子,其中对陷阱和源代码进行了很好的解释,您可以在此处找到:http://tips4java.wordpress.com/2009/08/02/disabled-panel/

我希望那里有一些帮助。

【讨论】:

  • 好吧:1) 禁用 (setEnabled(false)) 并不是真正的问题。您提到了一种方法,如果需要,可以由地图支持以保存初始状态。 2) 玻璃窗格的问题 - AFAIK - 是它仅可用于根窗格并覆盖其包含层次结构内的所有容器。因此,在我的情况下,我会遇到问题,因为我使用添加到 JFrame 分层窗格的弹出层中的 JInternalFrame,该层将位于玻璃窗格下方。
  • 我已经试过你的代码并且可以确认行为。我还可以确认它似乎与 MigLayout 直接相关。如果我删除它的所有用法并将所有内容放入流布局中,则叠加层看起来是正确的。明天我会玩它,看看有没有什么结果:)
  • 非常好,谢谢!我把头撞在墙上,试图解决这个问题,但没有成功。也许一些新的想法有助于提出解决方案:)
  • 我尝试了很多东西,可能和你尝试的一样,但无济于事。
  • 有趣的是,例如最小化/最大化...:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2012-02-29
  • 1970-01-01
  • 2014-12-11
  • 2016-09-28
  • 1970-01-01
  • 2011-08-27
相关资源
最近更新 更多