gpt4 book ai didi

java - 在 JComboBox 项中显示按钮

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:23:33 24 4
gpt4 key购买 nike

我目前有一个 JComboBox,我将其用作音频播放列表 - 我想要实现的是每个项目右侧的一个小“删除”按钮,我可以使用它从底层删除它模型,其中圆圈是:

实现此目标的最佳方法是什么?

我希望 JComboBox 中所有项目的按钮都相同。

demo screenshot

最佳答案

首先让我说这是一个有趣的问题(不久前 +1)。

我必须快速尝试并亲眼看看使用 JComboBox 实现想要的结果有多困难。我得到的结论(正如@trashgod 在上面的评论中所说)是这个对象从未被设计为具有其他组件,或者至少对我来说是这样的。

下面是一个示例,可以执行您想要的操作。您可以将它作为一个开始,但老实说,您应该忘记使用 JComboBox 来解决这个问题。

下面的示例绝不代表解决问题的正确方法。它只是显示了我尝试解决问题的结果。下面的代码不保留良好的实践规则,例如它将表示与功能混合在一起(渲染器删除了元素)。这实际上只是一个 hack 而不是真正的解决方案。

import java.awt.*;
import java.awt.event.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

public class ButtonCombo {

private JPanel getContent() throws MalformedURLException {
String[] ids = {"north", "west", "south", "east"};
JComboBox combo = new JComboBox(ids);
Icon removeIcon = new ImageIcon(new URL("http://filesharefreak.org/images/red_x.png"));
combo.setRenderer(new ButtonComboRenderer(removeIcon, combo));
JPanel panel = new JPanel();
panel.add(combo);
return panel;
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
try {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.add(new ButtonCombo().getContent());
JButton button = new JButton("OKOKO");
panel.add(button);
f.setContentPane(panel);
f.setSize(300, 160);
f.setLocation(200, 200);
f.setVisible(true);
} catch (MalformedURLException ex) {
Logger.getLogger(ButtonCombo.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
}

class ButtonComboRenderer implements ListCellRenderer {
Icon icon;
JPanel panel;
JLabel label;
JButton button;

public ButtonComboRenderer(Icon removeIcon, final JComboBox combo) {
icon = removeIcon;
label = new JLabel();
button = new JButton(icon);
button.setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
panel = new JPanel(new BorderLayout());
panel.add(label);
panel.add(button, BorderLayout.EAST);
panel.addMouseListener(new MouseAdapter() {

@Override
public void mousePressed(MouseEvent e) {
if (button.getX() < e.getX()) {
System.out.println("button contains the click remove the item");
combo.removeItem(label.getText());
}
}
});
}
//so we will install the mouse listener once
boolean isFirst = true;

@Override
public Component getListCellRendererComponent(JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
if (isFirst) {
isFirst = false;
list.addMouseListener(new MouseAdapter() {

@Override
public void mousePressed(MouseEvent e) {
panel.dispatchEvent(e);
e.consume();
}
});
}
String text = (String) value;
label.setText(text);
if(text == null)
button.setIcon(null);
else if(button.getIcon() == null)
button.setIcon(icon);
panel.setBackground(isSelected ? Color.red : Color.white);
panel.setForeground(isSelected ? Color.white : Color.black);
return panel;
}
}

我的最终建议和实现方式是:构建您自己的组件。通过将其与触发器和表示分离,使其可扩展和可修改,两者都使用 JComponent,因为它们反对使用渲染器。通过这种方式,您将能够在组件上捕获和提供事件,而不是像在这种情况下所有事件都由用于呈现的 JList 捕获。

下面是一个可以帮助您入门的示例。它不是最终的解决方案,但它提出了制作此类组件所涉及的许多重要问题。您应该使用提供的功能并将其全部相应地包装在一个组件中:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class MockJComboBox {

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
final JPanel popupContent = new JPanel(new GridLayout(0, 1));
popupContent.setBackground(Color.GREEN);
popupContent.add(new JLabel("Content of popupContent panel"));
popupContent.add(new JLabel("Content of popupContent panel"));
popupContent.add(new JLabel("Content of popupContent panel"));
popupContent.add(new JLabel("Content of popupContent panel"));
popupContent.add(new JLabel("Content of popupContent panel"));
popupContent.add(new JComboBox(new Object[]{"Content of popupContent panel"}));
final JButton popupCloseButton = new JButton("X");
popupContent.add(popupCloseButton);

final JScrollPane s = new JScrollPane(popupContent);
s.setPreferredSize(new Dimension(popupContent.getPreferredSize().width + s.getVerticalScrollBar().getPreferredSize().width
+ s.getBorder().getBorderInsets(s).left
+ s.getBorder().getBorderInsets(s).right, 100));

JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(200, 200));
final JButton popupOpenButton = new JButton();
panel.add(popupOpenButton);
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(panel);
final PopupFactory popupFactory = PopupFactory.getSharedInstance();
popupOpenButton.setAction(new AbstractAction("Open") {
private Popup popup;
private boolean isShown = false;

@Override
public void actionPerformed(ActionEvent e) {
if (isShown) {
popup.hide();
} else {
popup = popupFactory.getPopup(popupOpenButton, s,
popupOpenButton.getLocationOnScreen().x, popupOpenButton.getLocationOnScreen().y + popupOpenButton.getHeight());
popupCloseButton.setAction(new AbstractAction(popupCloseButton.getText()) {

@Override
public void actionPerformed(ActionEvent e) {
isShown = false;
popup.hide();
}
});
popup.show();
}
isShown = !isShown;
}
});
f.pack();
f.setVisible(true);
}
});
}
}

关于java - 在 JComboBox 项中显示按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11065282/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com