如何保持禁用的JTabbedPane选项卡看起来与它们处于活动状态时完全相同?

时间:2016-08-24 00:35:57

标签: java swing tabs jtabbedpane

我正在使用JTabbedPane并将其所有标签设置为禁用。与此同时,我需要让标签看起来就像它们处于活动状态时一样。我不需要它们在颜色上变灰。我使用 next 之前的按钮在标签之间移动。选项卡的唯一目的只是成为一个可视指示器。

我尝试了this代码回答。它可以工作,但如何正确地修改它,以便禁用的选项卡看起来与它们是活动标签时完全相同。

我指的是swing有效标签组件的默认外观

通过活动标签,我的意思是启用,无论是否被选中。

Three Swing tabs with tab2 selected

1 个答案:

答案 0 :(得分:2)

  

我将其所有标签设置为禁用。与此同时,我需要让标签看起来就像它们处于活动状态时一样。我不需要它们变成灰色。

也许您可以使用JLayerJTabbedPane#setTabComponentAt(Component)

  

(4)没有其他已知的用作视觉指示器的替代方案。

如何使用JSlider

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;

public class TabbedPaneTest {
  private int prev = 0;
  public JComponent makeUI() {
    JPanel p = new JPanel(new GridLayout(0, 1, 0, 5));
    p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

    JTabbedPane tabbedPane0 = new SmallTabbedPane();
    JTabbedPane tabbedPane1 = new SmallTabbedPane();
    JTabbedPane tabbedPane2 = new SmallTabbedPane() {
      @Override public void addTab(String title, Component content) {
        super.addTab(title, content);
        int currentIndex = getTabCount() - 1;
        setTabComponentAt(currentIndex, new JLabel(title));
        setComponentAt(currentIndex, content);
      }
    };

    initTabbedPane(tabbedPane0);
    p.add(new JLayer<JComponent>(tabbedPane0, new DisableInputLayerUI()));

    for (JTabbedPane tabs : Arrays.asList(tabbedPane1, tabbedPane2)) {
      initTabbedPane(tabs);
      tabs.setEnabledAt(0, false);
      tabs.setEnabledAt(1, false);
      tabs.setEnabledAt(2, false);
      tabs.setEnabledAt(3, false);
      p.add(tabs);
    }

    Dictionary<Integer, Component> labelTable = new Hashtable<>();
    int c = 0;
    for (String s : Arrays.asList("tab1", "tab2", "tab2", "tab4")) {
      JLabel l = new JLabel(s);
      if (c == 0) {
        resetForeground(l, Color.RED, Color.WHITE);
      }
      labelTable.put(c++, l);
    }
    JSlider slider = new JSlider(0, 3, 0);
    //slider.setEnabled(false);
    slider.setSnapToTicks(true);
    slider.setPaintTicks(true);
    slider.setLabelTable(labelTable);
    slider.setPaintLabels(true);
    slider.getModel().addChangeListener(e -> {
      BoundedRangeModel m = (BoundedRangeModel) e.getSource();
      int i = m.getValue();
      if (i != prev) {
        Dictionary dictionary = slider.getLabelTable();
        resetForeground(dictionary.get(i), Color.RED, Color.WHITE);
        resetForeground(dictionary.get(prev), Color.BLACK, null);
        slider.repaint();
        prev = i;
      }
    });
    p.add(new JLayer<JComponent>(slider, new DisableInputLayerUI()));

    JButton button = new JButton("next");
    button.addActionListener(e -> {
      int i = tabbedPane1.getSelectedIndex() + 1;
      int next = i >= tabbedPane1.getTabCount() ? 0 : i;
      tabbedPane0.setSelectedIndex(next);
      tabbedPane1.setSelectedIndex(next);
      tabbedPane2.setSelectedIndex(next);
      slider.setValue(next);
    });

    JPanel pp = new JPanel(new BorderLayout());
    pp.add(p, BorderLayout.NORTH);
    pp.add(button, BorderLayout.SOUTH);
    return pp;
  }
  private static void initTabbedPane(JTabbedPane tabs) {
    tabs.addTab("tab1", new JLabel());
    tabs.addTab("tab2", new JLabel());
    tabs.addTab("tab3", new JLabel());
    tabs.addTab("tab4", new JLabel());
  }
  private static void resetForeground(Object o, Color fc, Color bc) {
    if (o instanceof JComponent) {
      JComponent c = (JComponent) o;
      c.setForeground(fc);
        if (bc != null) {
            c.setOpaque(true);
            c.setBackground(bc);
        } else {
            c.setOpaque(false);
        }
    }
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new TabbedPaneTest().makeUI());
      f.setSize(320, 320);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class SmallTabbedPane extends JTabbedPane {
  @Override public Dimension getPreferredSize() {
    Dimension d = super.getPreferredSize();
    d.height = 24;
    return d;
  }
}

class DisableInputLayerUI extends LayerUI<JComponent> {
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    ((JLayer) c).setLayerEventMask(
      AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK
      | AWTEvent.MOUSE_WHEEL_EVENT_MASK | AWTEvent.KEY_EVENT_MASK
      | AWTEvent.FOCUS_EVENT_MASK | AWTEvent.COMPONENT_EVENT_MASK);
  }
  @Override public void uninstallUI(JComponent c) {
    ((JLayer) c).setLayerEventMask(0);
    super.uninstallUI(c);
  }
  @Override public void eventDispatched(AWTEvent e, JLayer<? extends JComponent> l) {
    if (e instanceof InputEvent) {
      ((InputEvent) e).consume();
    }
  }
}