2009-11-24 6 views
4

Я пытаюсь создать поле со списком, чтобы я мог использовать любой элемент управления, который я предпочитаю во всплывающем окне, в моем конкретном случае JTree. Посмотрев, как реализуется JComboBox, всплывающее окно действительно создается делегатом пользовательского интерфейса. Проблема в изменении этого заключается в том, что ее нужно будет повторно внедрить для каждого вида и стиля, чего я не хочу делать ...Как настроить JComboBox так, чтобы всплывающее окно было JTree (вместо списка)?

Я в основном хочу компонент, который имеет внешний вид JComboBox (в текущем внешнем виде), а всплывающее окно - JTree (в текущем внешнем виде).

Что это самый простой способ сделать это?

+1

Я не уверен, что понимаю концепцию. Когда дерево всплывает, вы сможете выбрать узел из дерева и отобразить это значение в поле со списком? Когда дерево всплывает, это узел в дереве, уже выбранном/расширенном, на основе значения в поле со списком? Или это просто способ отображения дерева щелчком мыши? – camickr

+0

Первый случай: дерево всплывает, узел уже выбран (если есть), щелкните узел, JComboBox запускает ActionEvent, чтобы сигнализировать о том, что выбор изменился, и дерево исчезло. На самом деле у меня есть способ отображения дерева щелчком мыши (с помощью JCommandButton в пакете компонентов фламинго). – Carcassi

ответ

2

JComboBox сам по себе не может делать то, что вы хотите. Если вы абсолютно согласны с концепцией того, что он действует как JComboBox, вы можете сделать JButton всплывающим JPanel при щелчке. Тогда JPanel может иметь все, что вы хотите внутри него (JTree и т. Д.).

+0

Да, именно так я делаю это прямо сейчас. Проблема в том, что я хочу внедрить это в JTable в качестве TableCellEditor, а наличие кнопки в нем довольно уродливое ...: - / – Carcassi

0

Вам просто нужно расширить BasicComboBoxUI и затем переопределить необходимые методы, как

public static ComponentUI createUI(JComponent c) 

и

protected ComboPopup createPopup() 

Создание пользовательского ComboPopup может потребовать от вас поставить некоторые усилия, где вы не можете использовать BasicComboPopUp, поскольку он расширяет JPopUpMenu

public class BasicComboPopup extends JPopupMenu implements ComboPopup 

Так что в вашем случае вы ma y хочу расширить JTree и реализовать ComboPopup.

Я сомневаюсь, что «проблема в изменении заключается в том, что ее нужно будет переделать для каждого вида и ощущения». Я не думаю, что будет проблема повторной реализации.

BasicComboPopup выглядит по-разному в разных взглядах и чувствах, потому что это JPopupMenu, который, в свою очередь, будет иметь делегаты пользовательского интерфейса. Поэтому, если вы просто расширяете JTree, у вас не должно быть проблем с разным внешним видом.

0

Ответ на использование кнопки, которая вызывает JPanel с помощью JTree, верна. В ответ на комментарий Carcassi вы можете использовать собственный TableCellRenderer, чтобы изменить его, чтобы он не выглядел как традиционная кнопка.

1

У меня было желание создать что-то подобное.

Сначала я попытался реализовать что-то по линиям, предложенным Варуном, но это оказалось немного беспорядочным, и я немного нервничаю, когда начинаю играть с объектами ComponentUI (я бы предпочел оставить этот вид вещи к L & F). Если у кого-то есть хороший пример этого, мне было бы интересно его увидеть.

Затем я попробовал кнопку подход ... и думал, что я хотел бы поделиться код с сообществом SO:

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 
import javax.swing.plaf.basic.BasicInternalFrameUI; 
import javax.swing.plaf.metal.MetalComboBoxIcon; 

public class MockJComboBox extends JPanel { 

    private boolean _isPoppedUp = false; 

    public MockJComboBox(String label, final JComponent toShow) { 
    setLayout(new BorderLayout()); 
    JLabel jLabel = new JLabel(label); 
    jLabel.setBackground(Color.WHITE); 
    add(jLabel, BorderLayout.CENTER); 
    Icon icon = new MetalComboBoxIcon(); 

    final JInternalFrame popup = new JInternalFrame(null, false, false, false, false); 
    final JPanel panel = new JPanel(new BorderLayout()); 
    panel.add(new JScrollPane(toShow), BorderLayout.CENTER); 
    if(!(System.getProperty("os.name").startsWith("Mac OS"))){ 
     BasicInternalFrameUI ui = (BasicInternalFrameUI) popup.getUI(); 
     ui.getNorthPane().setPreferredSize(new Dimension(0,0)); 
    } 
    popup.setBorder(null); 
    popup.setContentPane(panel); 
    popup.pack(); 
    popup.setVisible(true); 

    final JButton dropDownButton = new JButton(icon); 
    dropDownButton.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
     _isPoppedUp = !_isPoppedUp; 
     Container parent = getParent(); 
     if (_isPoppedUp) { 
      popup.setLocation(panel.getX(), panel.getY() + panel.getHeight()); 
      popup.setSize(panel.getWidth(), toShow.getHeight()); 
      parent.add(popup); 
     } else { 
      parent.remove(popup); 
      parent.repaint(); 
     } 
     } 
    }); 
    add(dropDownButton, BorderLayout.EAST); 
    } 

    public boolean isPoppedUp() { 
    return _isPoppedUp; 
    } 
} 

Если вы заметили какие-либо ошибки или есть предложения о том, как улучшить этот код, I» буду благодарен за ваши комментарии!

0

Далее веб-исследование показало, что Jidesoft, которые описывают себя как «профессиональный Java и поставщик компонентов Swing» производят пакет под названием JIDE Grids, который включает в себя AbstractComboBox - описание, для которого предполагает, что это будет делать это.

Однако это платный пакет, и я не пробовал его ... Если кто-то использовал это, могли бы они прокомментировать опыт?