2016-08-24 9 views
0

Я использую JTabbedPane, и я установил все его вкладки для отключения. В то же время мне нужно, чтобы вкладки выглядели так же, как когда они активны. Мне не нужно, чтобы они были серыми в цветах. Я перемещаюсь между вкладками, используя следующий и предыдущий кнопок. Единственная цель вкладок - просто визуальный индикатор.Как сохранить внешний вид отключенных вкладок JTabbedPane, чтобы они выглядели точно так, как только они активны?

Я попробовал this код ответа. Он работает, но как правильно его изменить, чтобы заблокированные вкладки выглядели точно так же, как активные вкладки.

Я имею в виду выглядит по умолчанию свинга активных вкладок компонентов:

По активной вкладки Я имею в виду только включена независимо от того, выбран ли он или нет.

Three Swing tabs with tab2 selected

+1

Это не путает пользователя, кто может задаться вопросом, почему кнопки, которые _appear_ не работают, не работают? Помогло бы оно расширить базовую [* проблему *] (http://meta.stackoverflow.com/q/66377/163188)? – trashgod

+0

@trashgod ** (1) ** Это не путает пользователей, потому что приложение предназначено для решения определенного математического вопроса *, известного своей аудитории *. Пользователь вводит поля в 'tab1', а затем нажимает следующий. 'tab2' будет использовать данные из' tab1' для подготовки некоторых промежуточных результатов. Пользователь загружает необходимые поля 'tab2' .. и так далее. Последняя вкладка будет содержать окончательный результат. ** (2) ** Требуется заполнить поля одной вкладки, прежде чем переходить к следующему. ** (3) ** Красиво видеть визуальный индикатор, чтобы показать, какой пользователь в данный момент находится. ** (4) ** Ни одна другая альтернатива, известная мне для использования в качестве визуального индикатора. –

+2

А, благодарю вас за разработку; для строгой модальной навигации такого рода я могу рассмотреть «CardLayout», для [example] (http://stackoverflow.com/a/5655843/230513), отключение кнопок до тех пор, пока текущая панель не будет завершена. – trashgod

ответ

2

Я поставил все свои вкладки, быть отключены. В то же время мне нужно, чтобы вкладки выглядели так же, как когда они активны. Мне не нужно, чтобы они были серыми в цветах.

Возможно, вы можете использовать JLayer или JTabbedPane#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(); 
    } 
    } 
} 
+0

Спасибо .. Я пробую код, он работает нормально. Но можете ли вы, пожалуйста, сжать код, чтобы использовать только один JTabbedPane (один из двух, который выглядит включенным), потому что это сделает код более понятным для меня^_^ –

+0

Я достиг себе того, что я попросил в предыдущем комментарии. Я ценю ваши усилия во всем коде. Единственной частью, требуемой для моей ситуации, является просто расширенный анонимный класс, используемый переменной 'tabbedPane2'. И это кажется более простым, чем подход, достигнутый с помощью 'tabbedPane0', который использует' JLayer', который я только что представил из этого ответа. Большое спасибо^_ ^ –