最近、同様の質問に対する解決策を投稿したので、将来の読者のためにここでも共有する必要があると思いました. JLabel
コンポーネントは、ここではメニュー項目として使用されていますが、 ではJMenuItem
使用できないようですJScrollPane
。メニュー項目のmouseListener
動作を模倣するために、各ラベルに が追加されます。つまり、マウスの開始/終了時に色が変化し、項目をクリックするとアクションが実行されます (この場合、ラベルのテキストが出力されます。次に何が続くかを決定するために使用できます)。必要に応じてscrollPane.setPreferredSize
、マウスが項目に出入りするときの色だけでなく、(便宜上、JMenuItem の現在の LookAndFeel で使用されているデフォルトの色が使用されている場合でも) を調整する必要がある場合があります。
JLabel のテキストでタグを使用する理由は<html>
、(項目の上にマウスを移動すると) 背景色がスクロールペインの各項目の幅を埋めるようにし、背景色をテキストの終わりまで適用しないようにするためです。 . 選択したテキストを読むと、<html>
タグが削除されます。
MenuExample.java
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public class MenuExample {
Random rand = new Random();
Color menuBackCol;
Color mItemBackCol;
Color mItemForegCol;
Color mItmSelBackCol;
Color mItmSelForegCol;
MenuExample() {
menuBackCol = UIManager.getColor("Menu.background");
mItemBackCol = UIManager.getColor("MenuItem.background");
mItemForegCol = UIManager.getColor("MenuItem.foreground");
mItmSelBackCol = UIManager.getColor("MenuItem.selectionBackground");
mItmSelForegCol = UIManager.getColor("MenuItem.selectionForeground");
Box box = new Box(BoxLayout.Y_AXIS);
for (int i = 0; i < 250; i++) {
box.add(Box.createRigidArea(new Dimension(0, 2))); // creates space between the components
JLabel lbl = new JLabel("<html>  " + i + ": " + rand.nextInt(10000) + "</html>");
lbl.setOpaque(true);
lbl.setBackground(mItemBackCol);
lbl.addMouseListener(
new LabelController(lbl, mItemBackCol, mItemForegCol, mItmSelBackCol, mItmSelForegCol));
box.add(lbl);
}
JScrollPane scrollPane = new JScrollPane(box);
scrollPane.getVerticalScrollBar().setUnitIncrement(20); // adjusts scrolling speed
scrollPane.setPreferredSize(new Dimension(100, 300));
scrollPane.setBorder(BorderFactory.createEmptyBorder());
scrollPane.getViewport().setBackground(menuBackCol);
JMenuBar mb = new JMenuBar();
JMenu menu = new JMenu("Menu");
JMenu submenu = new JMenu("Sub Menu");
submenu.add(scrollPane);
menu.add(new JMenuItem("Item 1"));
menu.add(new JMenuItem("Item 2"));
menu.add(new JMenuItem("Item 3"));
menu.add(submenu);
mb.add(menu);
JFrame f = new JFrame("Menu with ScrollBar Example");
f.setJMenuBar(mb);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(640, 480);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String args[]) {
new MenuExample();
}
}
LabelController.java
import java.awt.event.MouseEvent;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LabelController implements MouseListener {
JLabel lbl;
Color mItemBackCol;
Color mItemForegCol;
Color mItmSelBackCol;
Color mItmSelForegCol;
public LabelController(JLabel lbl, Color mItemBackCol, Color mItemForegCol, Color mItmSelBackCol,
Color mItmSelForegCol) {
this.lbl = lbl;
this.mItemBackCol = mItemBackCol;
this.mItemForegCol = mItemForegCol;
this.mItmSelBackCol = mItmSelBackCol;
this.mItmSelForegCol = mItmSelForegCol;
}
@Override
public void mouseClicked(MouseEvent e) {
String selectedText = lbl.getText().replaceAll("<[^>]*>", "").replace(" ","").trim();
System.out.println(selectedText);
javax.swing.MenuSelectionManager.defaultManager().clearSelectedPath(); // close the menu
lbl.setBackground(mItemBackCol);
lbl.setForeground(mItemForegCol);
}
@Override
public void mouseEntered(MouseEvent e) {
lbl.setBackground(mItmSelBackCol);
lbl.setForeground(mItmSelForegCol);
}
@Override
public void mouseExited(MouseEvent e) {
lbl.setBackground(mItemBackCol);
lbl.setForeground(mItemForegCol);
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
}