현재 마우스 오른쪽 버튼을 클릭 할 때 새 항목을 인스턴스화하고 JMenu
해당 위치를 마우스 위치로 설정하여 오른쪽 클릭 컨텍스트 메뉴를 만들고 있습니다. 더 좋은 방법이 있습니까?
답변
setVisible(true)
메뉴를 수동으로 호출 하고 있을 것입니다 . 이로 인해 메뉴에서 불쾌한 버그가 발생할 수 있습니다.
이 show(Component, int x, int x)
메서드는 필요한 모든 작업을 처리합니다 (마우스 오버시 항목을 강조 표시하고 필요한 경우 팝업 닫기). using setVisible(true)
은 추가 동작을 추가하지 않고 메뉴 만 표시합니다.
오른쪽 클릭 팝업 메뉴를 만들려면 간단히 JPopupMenu
.
class PopUpDemo extends JPopupMenu {
JMenuItem anItem;
public PopUpDemo() {
anItem = new JMenuItem("Click Me!");
add(anItem);
}
}
그런 다음 MouseListener
메뉴를 팝업하려는 구성 요소에 사용자 지정 을 추가 하기 만하면됩니다.
class PopClickListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if (e.isPopupTrigger())
doPop(e);
}
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger())
doPop(e);
}
private void doPop(MouseEvent e) {
PopUpDemo menu = new PopUpDemo();
menu.show(e.getComponent(), e.getX(), e.getY());
}
}
// Then on your component(s)
component.addMouseListener(new PopClickListener());
물론 자습서에는 약간 더 자세한 설명이 있습니다.
참고 : 팝업 메뉴가 사용자가 클릭 한 위치에서 벗어난 곳에 표시되는 경우 x 및 y 좌표에 대해 e.getXOnScreen()
및 e.getYOnScreen()
메서드를 사용해보십시오 .
답변
이 질문은 약간 오래되었습니다-답변과 튜토리얼도 마찬가지입니다.
Swing에서 popupMenu를 설정하는 현재 API는 다음과 같습니다.
myComponent.setComponentPopupMenu(myPopupMenu);
이렇게하면 마우스 및 키보드 트리거 모두에 대해 자동으로 표시됩니다 (후자는 LAF에 따라 다름). 또한 컨테이너의 자식간에 동일한 팝업을 재사용 할 수 있습니다. 해당 기능을 활성화하려면 :
myChild.setInheritsPopupMenu(true);
답변
클래스 사용 방법을 설명하는 The Java Tutorials 의 How to Use Menus 기사 에 Bringing Up a Popup Menu 에 대한 섹션이 있습니다 .JPopupMenu
튜토리얼의 예제 코드 MouseListener
는 팝업 메뉴를 표시해야하는 구성 요소에 를 추가 하고 그에 따라 메뉴를 표시하는 방법을 보여줍니다 .
(설명하는 방법은 튜토리얼이 구성 요소에 팝업 메뉴를 표시하는 방법을 제시하는 방법과 상당히 유사합니다.)
답변
다음 코드 Windows
는 복사, 잘라 내기, 붙여 넣기, 모두 선택, 실행 취소 및 다시 실행 기능으로 알려진 기본 컨텍스트 메뉴를 구현 합니다. 또한 작동 Linux
과 Mac OS X
:
import javax.swing.*;
import javax.swing.text.JTextComponent;
import javax.swing.undo.UndoManager;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class DefaultContextMenu extends JPopupMenu
{
private Clipboard clipboard;
private UndoManager undoManager;
private JMenuItem undo;
private JMenuItem redo;
private JMenuItem cut;
private JMenuItem copy;
private JMenuItem paste;
private JMenuItem delete;
private JMenuItem selectAll;
private JTextComponent textComponent;
public DefaultContextMenu()
{
undoManager = new UndoManager();
clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
addPopupMenuItems();
}
private void addPopupMenuItems()
{
undo = new JMenuItem("Undo");
undo.setEnabled(false);
undo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
undo.addActionListener(event -> undoManager.undo());
add(undo);
redo = new JMenuItem("Redo");
redo.setEnabled(false);
redo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
redo.addActionListener(event -> undoManager.redo());
add(redo);
add(new JSeparator());
cut = new JMenuItem("Cut");
cut.setEnabled(false);
cut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
cut.addActionListener(event -> textComponent.cut());
add(cut);
copy = new JMenuItem("Copy");
copy.setEnabled(false);
copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
copy.addActionListener(event -> textComponent.copy());
add(copy);
paste = new JMenuItem("Paste");
paste.setEnabled(false);
paste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
paste.addActionListener(event -> textComponent.paste());
add(paste);
delete = new JMenuItem("Delete");
delete.setEnabled(false);
delete.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
delete.addActionListener(event -> textComponent.replaceSelection(""));
add(delete);
add(new JSeparator());
selectAll = new JMenuItem("Select All");
selectAll.setEnabled(false);
selectAll.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
selectAll.addActionListener(event -> textComponent.selectAll());
add(selectAll);
}
private void addTo(JTextComponent textComponent)
{
textComponent.addKeyListener(new KeyAdapter()
{
@Override
public void keyPressed(KeyEvent pressedEvent)
{
if ((pressedEvent.getKeyCode() == KeyEvent.VK_Z)
&& ((pressedEvent.getModifiersEx() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0))
{
if (undoManager.canUndo())
{
undoManager.undo();
}
}
if ((pressedEvent.getKeyCode() == KeyEvent.VK_Y)
&& ((pressedEvent.getModifiersEx() & Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0))
{
if (undoManager.canRedo())
{
undoManager.redo();
}
}
}
});
textComponent.addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent releasedEvent)
{
handleContextMenu(releasedEvent);
}
@Override
public void mouseReleased(MouseEvent releasedEvent)
{
handleContextMenu(releasedEvent);
}
});
textComponent.getDocument().addUndoableEditListener(event -> undoManager.addEdit(event.getEdit()));
}
private void handleContextMenu(MouseEvent releasedEvent)
{
if (releasedEvent.getButton() == MouseEvent.BUTTON3)
{
processClick(releasedEvent);
}
}
private void processClick(MouseEvent event)
{
textComponent = (JTextComponent) event.getSource();
textComponent.requestFocus();
boolean enableUndo = undoManager.canUndo();
boolean enableRedo = undoManager.canRedo();
boolean enableCut = false;
boolean enableCopy = false;
boolean enablePaste = false;
boolean enableDelete = false;
boolean enableSelectAll = false;
String selectedText = textComponent.getSelectedText();
String text = textComponent.getText();
if (text != null)
{
if (text.length() > 0)
{
enableSelectAll = true;
}
}
if (selectedText != null)
{
if (selectedText.length() > 0)
{
enableCut = true;
enableCopy = true;
enableDelete = true;
}
}
if (clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor) && textComponent.isEnabled())
{
enablePaste = true;
}
undo.setEnabled(enableUndo);
redo.setEnabled(enableRedo);
cut.setEnabled(enableCut);
copy.setEnabled(enableCopy);
paste.setEnabled(enablePaste);
delete.setEnabled(enableDelete);
selectAll.setEnabled(enableSelectAll);
// Shows the popup menu
show(textComponent, event.getX(), event.getY());
}
public static void addDefaultContextMenu(JTextComponent component)
{
DefaultContextMenu defaultContextMenu = new DefaultContextMenu();
defaultContextMenu.addTo(component);
}
}
용법:
JTextArea textArea = new JTextArea();
DefaultContextMenu.addDefaultContextMenu(textArea);
이제 textArea
마우스 오른쪽 버튼을 클릭하면 컨텍스트 메뉴가 나타납니다.
답변
@BullyWillPlaza가 제안한 방법의 사용법을 수정하겠습니다. 이유는 contextMenu에만 textArea를 추가하려고 할 때 표시되지 않으며 contextMenu와 일부 패널에 모두 추가하면 다음과 같이 표시됩니다. 디자인 편집기로 전환하려고하면 다른 부모 이중 연결.
TexetObjcet.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)){
contextmenu.add(TexetObjcet);
contextmenu.show(TexetObjcet, 0, 0);
}
}
});
팝업이 필요한 텍스트 객체에 대해 마우스 리스너를 이와 같이 만드십시오. 이것이 할 일은 텍스트 개체를 마우스 오른쪽 버튼으로 클릭하면 해당 팝업을 추가하고 표시하는 것입니다. 이렇게하면 해당 오류가 발생하지 않습니다. @BullyWillPlaza가 만든 솔루션은 프로그램에서 구현하기에 매우 훌륭하고 풍부하며 빠르므로 원하는 방법을 확인해야합니다.