私は現在、オーディオプレイリストとして使用しているJComboBoxを持っています。達成したいのは、私が使用できる各アイテムの右側に少し「削除」ボタンです円がどこにある下にあるモデルからそれを削除しますか:JComboBoxアイテムの表示ボタン
これを達成する最良の方法は何でしょうか?
JComboBoxのすべての項目でボタンを同じにしたいと思います。
私は現在、オーディオプレイリストとして使用しているJComboBoxを持っています。達成したいのは、私が使用できる各アイテムの右側に少し「削除」ボタンです円がどこにある下にあるモデルからそれを削除しますか:JComboBoxアイテムの表示ボタン
これを達成する最良の方法は何でしょうか?
JComboBoxのすべての項目でボタンを同じにしたいと思います。
私は、これは興味深い質問(しばらく前に1)であることを言ってみましょう。
JComboBox
で希望の結果を達成することがどれほど難しいかをすぐに試してみる必要がありました。私が得た結論(@trashgodは上記のコメントで言います)は、このオブジェクトが他のコンポーネントを持つようには設計されていないか、少なくとも私にはこのように感じられました。
以下は、何か必要なものを行うサンプルです。あなたはこれを最初に使うことができますが、正直言ってこの問題にはJComboBox
を使用することを忘れてしまいます。
以下のサンプルは、問題に近づく正しい方法を示していません。それは単に問題に近づく試みの結果を示しています。以下のコードでは、優れた実務ルールを保持していません。プレゼンテーションと機能が混在しています(レンダラーが要素を削除します)。これは実際には実際のソリューションではないハックです。
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;
}
}
私の最終勧告と私はそれを行うような方法は次のとおりです。
BUILD独自のコンポーネント。トリガーとプレゼンテーションから分離して拡張性と変更可能にしてください。どちらも、レンダラーの使用に反対するので、
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);
}
});
}
}
+1、素晴らしい答え、ありがとう! – berry120
あなたは2) 'JComboBoxの中のすべてのアイテムのために' '1)' 1項にJLabelのを入れてのJButtonをしたいですまたは – mKorbel
@mKorbelあなたの最初のポイントは何を意味するのか分かりませんか?しかし、2番目のポイントは、はい。 – berry120
私は1つの重要な問題を見て、JComboBox drop_downはMouse_clickをItem(Java1.4以上)の後に持ち去り、それに同意して受け入れるのですか。 – mKorbel