: 확인의 대화()를 열어가 InputVerifier의 모든 구현 무효 있습니다. 그들은 그들의 계약을 위반했다. API :
이 방법은 부작용이 없어야한다.
"should"는 실제로 "~해야합니다"를 의미합니다. 부작용에 대한 올바른 위치는 shouldField입니다.
둘째, 제대로의 shouldYieldFocus에 (메시지 대화 상자를 표시) 부작용을 이동하는 것은 물론 작동하지 않습니다 ... bug (THEY call it feature request ;-)에, 그건 hack-되는 10 년 나이 in the top 10 RFEs
입니다 때문에 모든 가능한 해킹이 버그를 해결 해킹 다른 옵션이있는 비트를 연주 후
업데이트
:-) 얻을 수있는 버그 주위 @의 dareurdrem의의 MouseListener, 여기에 또 다른 해킹 좋은 - 그것은 취성의 모든 해킹 ar
: 전자 기본적인 접근 방식은 UI에 의해 설치된 수신기에 후크하는 것입니다 마우스 동작을 해킹
(그리고 LAF 토글 생존하지 않습니다, 동적 토글이 필요한 경우 다시 설치해야합니다)
- 은 원래
- 먼저 초점을 요청 직접 프레스 이벤트에 대한 원래의
- 명까지 대부분의 이벤트를 사용자 정의 리스너를 구현 찾을 : 아무것도하지하지 않을 경우, 원래 대리자를 굴복 경우
,
포커스 이벤트가 비동기적일 수 있으므로 포커스가 맞는지 확인해야합니다. 차례로 호출하면 아무도 반대하지 않을 경우 릴리스를 보내야합니다.
또 다른 특징은 (defaultButton에 대한) rootPane의 눌려진 동작입니다. 무조건 doClick을 호출하여 inputVerifiers를 존중하지 않고 완료됩니다.
- 을 찾을 수의 rootPane의 누르면 동작
- 는 잠재적으로 vetoing가 InputVerifier를 확인하는 사용자 지정 작업을 구현한다 : 즉,이 액션에 후킹의 MouseListener 후킹과 같은 패턴을 따라 해킹 할 수있는 원래의 위임 그렇지 않으면, 아무것도하지 않고 다른
그 라인을 따라 수정 예제 : 사실
public class VerifierTest implements Runnable {
private static final long serialVersionUID = 1L;
@Override
public void run() {
InteractiveTestCase.setLAF("Win");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 200);
JTextField tf = new JTextField("TextField1");
tf.setInputVerifier(new PassVerifier());
frame.add(tf, BorderLayout.NORTH);
final JButton b = new JButton("Button");
frame.add(b);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Button clicked");
}
});
// hook into the mouse listener
replaceBasicButtonListener(b);
frame.add(new JTextField("not validating, something else to focus"),
BorderLayout.SOUTH);
frame.getRootPane().setDefaultButton(b);
// hook into the default button action
Action pressDefault = frame.getRootPane().getActionMap().get("press");
frame.getRootPane().getActionMap().put("press", new DefaultButtonAction(pressDefault));
frame.setVisible(true);
}
protected void replaceBasicButtonListener(AbstractButton b) {
final BasicButtonListener original = getButtonListener(b);
if (original == null) return;
Hacker l = new Hacker(original);
b.removeMouseListener(original);
b.addMouseListener(l);
}
public static class Hacker implements MouseListener {
private BasicButtonListener original;
/**
* @param original the listener to delegate to.
*/
public Hacker(BasicButtonListener original) {
this.original = original;
}
/**
* Hook into the mousePressed: first request focus and
* check its success before handling it.
*/
@Override
public void mousePressed(final MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
if(e.getComponent().contains(e.getX(), e.getY())) {
// check if we can get the focus
e.getComponent().requestFocus();
invokeHandleEvent(e);
return;
}
}
original.mousePressed(e);
}
/**
* Handle the pressed only if we are focusOwner.
*/
protected void handlePressed(final MouseEvent e) {
if (!e.getComponent().hasFocus()) {
// something vetoed the focus transfer
// do nothing
return;
} else {
original.mousePressed(e);
// need a fake released now: the one from the
// original cycle might never has reached us
MouseEvent released = new MouseEvent(e.getComponent(), MouseEvent.MOUSE_RELEASED,
e.getWhen(), e.getModifiers(),
e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()
);
original.mouseReleased(released);
}
}
/**
* focus requests might be handled
* asynchronously. So wrap the check
* wrap the block into an invokeLater.
*/
protected void invokeHandleEvent(final MouseEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
handlePressed(e);
}
});
}
@Override
public void mouseClicked(MouseEvent e) {
original.mouseClicked(e);
}
@Override
public void mouseReleased(MouseEvent e) {
original.mouseReleased(e);
}
@Override
public void mouseEntered(MouseEvent e) {
original.mouseEntered(e);
}
@Override
public void mouseExited(MouseEvent e) {
original.mouseExited(e);
}
}
public static class DefaultButtonAction extends AbstractAction {
private Action original;
/**
* @param original
*/
public DefaultButtonAction(Action original) {
this.original = original;
}
@Override
public void actionPerformed(ActionEvent e) {
JRootPane root = (JRootPane) e.getSource();
JButton owner = root.getDefaultButton();
if (owner != null && owner.getVerifyInputWhenFocusTarget()) {
Component c = KeyboardFocusManager
.getCurrentKeyboardFocusManager()
.getFocusOwner();
if (c instanceof JComponent && ((JComponent) c).getInputVerifier() != null) {
if (!((JComponent) c).getInputVerifier().shouldYieldFocus((JComponent) c)) return;
}
}
original.actionPerformed(e);
}
}
/**
* Returns the ButtonListener for the passed in Button, or null if one
* could not be found.
*/
private BasicButtonListener getButtonListener(AbstractButton b) {
MouseMotionListener[] listeners = b.getMouseMotionListeners();
if (listeners != null) {
for (MouseMotionListener listener : listeners) {
if (listener instanceof BasicButtonListener) {
return (BasicButtonListener) listener;
}
}
}
return null;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new VerifierTest());
}
public static class PassVerifier extends InputVerifier {
/**
* Decide whether or not the input is valid without
* side-effects.
*/
@Override
public boolean verify(JComponent input) {
final JTextField tf = (JTextField) input;
String pass = tf.getText();
if (pass.equals("Manish"))
return true;
return false;
}
/**
* Implemented to ask the user what to do if the input isn't valid.
* Note: not necessarily the best usability, it's mainly to
* demonstrate the different effects on not/agreeing with
* yielding focus transfer.
*/
@Override
public boolean shouldYieldFocus(final JComponent input) {
boolean valid = super.shouldYieldFocus(input);
if (!valid) {
String message = "illegal value: " + ((JTextField) input).getText();
int goAnyWay = JOptionPane.showConfirmDialog(input, "invalid value: " +
message + " - go ahead anyway?");
valid = goAnyWay == JOptionPane.OK_OPTION;
}
return valid;
}
}
}
showMessageDialog 호출을 Runnable로 랩핑하여 SwingUtilities :: invokeLater (Runnable)에 전달하십시오. – gd1
@ gd14 안녕하세요, 명시된 방식대로 시도했지만 작동하지 않는 것 같습니다. 수정 된 코드는 다음과 같습니다. - final String message = "잘못된 값 :"+ tf.getText(); \t javax.swing.SwingUtilities.invokeLater (새의 Runnable() { \t \t 공공 무효 실행() { \t \t \t JOptionPane.showMessageDialog (NULL, 메시지, \t \t \t \t \t "잘못된 값", JOptionPane.ERROR_MESSAGE); \t \t} \t}); \t false를 반환합니다. – dareurdream
알겠습니다. OS 및 Java 버전은 무엇입니까? OSX에서 Java 1.6을 사용하고 있으며 정상적으로 작동합니다. – gd1