1

I am trying to edit a JComboBox so that it has an "Delete" Button (Image/Icon) in each of its Cells to delete a specific entry. I have already tried creating a custom CellRenderer, i was able to add Images but not to react to the MouseClicks (at least i don't know which Image/Cell was clicked), i can only get the X and Y Positions. But i do not know the Positions of the Images.

enter image description here

I'd appreciate it if anyone would have an Idea on how to do this, i already tried googleing, but i didn't find anything decent.

Marcel
  • 1,509
  • 1
  • 17
  • 39
  • Extremely hard to do, as the popup is another window which is displayed through the combobox UI and does not have any direct connection to the original combobox component whatsoever. Additionally, the implementation details might differ depending on the look and feel you use. As a heartfelt advice: find another solution. If you are not willing to take this advice, read some basics about programming your own look and feel components and have a look at BasicComboBoxUI as a reference. – mtj Aug 23 '16 at 13:41
  • @mtj Own look And Feel is not an Option, it is a commerical application which uses the system look and feel and that is how it is supposed to stay i guess. Anyways making an own look and feel just for this isn't worth the function – Marcel Aug 23 '16 at 13:42
  • there is an ComboBoxEditor with JTable(with unwanted numbers of Columns), then is easy and possible, to store Booloean value in XxxTableModel with AbstractButton, maybe directly undecorated JToggleButton, there is one problem, you can't to store some JCcomponents and with Icon without using JButtons Components, otherwise is there required huge effort – mKorbel Aug 23 '16 at 13:46
  • @mKorbel Care to elaborate? The only references regarding ComboBoxEditor and JTable that I found are about using a combo box as a table cell editor. – mtj Aug 23 '16 at 13:48
  • to shows JTable instead of JList (default implementations in API), don't play with mouseEvents and with JList, because popup goes away, is hide immediatelly – mKorbel Aug 23 '16 at 13:50
  • I'm sure that JTable instead of JList (as ComboBoxEditor) is there a few times and in SSCCE/MCVE form – mKorbel Aug 23 '16 at 13:51
  • [maybe will help you as an example about some complex example by using JTable](http://stackoverflow.com/a/11859210/714968) – mKorbel Aug 23 '16 at 13:53
  • Thought so: you provide a nice example of how to add a combo box to a table, but not the other way around. Alas, my opinon of "can't be done" still stands. – mtj Aug 23 '16 at 13:57

2 Answers2

3

This might(?) give you some ideas.

It uses the JLayer class to decorate the JList and paint the close icon (well a simple "X" character in the example).

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
import javax.swing.plaf.basic.*;

class LayerList extends JPanel
{
    LayerList()
    {
        LayerUI<JComponent> layerUI = new LayerUI<JComponent>()
        {
            public void paint(Graphics g, JComponent c)
            {
                super.paint(g, c);

                JLayer layer = (JLayer)c;
                JList list = (JList)layer.getView();
                int selected = list.getSelectedIndex();

                if (selected == -1 ) return;

                Rectangle area = list.getCellBounds(selected, selected);

                g.drawString("X", area.width - 15, area.y + area.height - 3);
            }

            public void installUI(JComponent c)
            {
                super.installUI(c);

                JLayer jlayer = (JLayer)c;
                jlayer.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
            }

            public void uninstallUI(JComponent c)
            {
                super.uninstallUI(c);

                // reset the layer event mask
                ((JLayer) c).setLayerEventMask(0);
            }

            @Override
            protected void processMouseEvent(MouseEvent e, JLayer l)
            {
//              e.consume();

                if (e.getID() == MouseEvent.MOUSE_RELEASED)
                {
                    JList list = (JList)e.getComponent();
                    int selected = list.getSelectedIndex();
                    Rectangle area = list.getCellBounds(selected, selected);

                    if (e.getX() >= area.width - 15)
                    {
                        e.consume();
                        DefaultComboBoxModel model = (DefaultComboBoxModel)list.getModel();
                        model.removeElementAt( selected );
                        list.setSelectedIndex(selected);
                    }
                }
            }
        };

        String[] data = { "a", "b", "c", "d", "e", "f" };

        JComboBox<String> comboBox = new JComboBox<String>(data);

        Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
        BasicComboPopup popup = (BasicComboPopup)child;
        JList list = (JList)popup.getList();
        Container c = SwingUtilities.getAncestorOfClass(JScrollPane.class, list);
        JScrollPane scrollPane = (JScrollPane)c;
        scrollPane.setViewportView( new JLayer<JComponent>(list, layerUI) );


        setLayout( new BorderLayout() );
        add( comboBox );
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("Layer List");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new LayerList() );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }
}

Read the section from the Swing tutorial on How to Decorate Components with the JLayer Class for more information and examples of using the JLayer class.

camickr
  • 321,443
  • 19
  • 166
  • 288
0

Build your UI with panels. Build a panel containing a label and a button (you can add an image as background). Add this panel as item to the combobox.

http://www.codejava.net/java-se/swing/create-custom-gui-for-jcombobox

Ueda Ichitaka
  • 71
  • 1
  • 8
  • Already thought about that, but i think its kind of a dirty way, that will be my last resort. – Marcel Aug 23 '16 at 15:59