1

入力時に Java の KeyListener を使用して JLabel を更新しようとしています。基本的に、私は自分のテキストフィールドを作成しています。ここに私が持っているものがあります:

/**
     * Constructor for objects of class Dictionary
     */
    public Dictionary()
    {
        frame = new JFrame();
        frame.setTitle("Shori Dictionary");
        frame.setLayout(new GridBagLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

private void createWord()
    {
        frame.remove(pane);
        pane = new PaintPane(field.getImage());
        pane.setLayout(new BorderLayout());
        frame.add(pane);
        frame.pack();

        newWord = new JLabel(text);
        newWord.setFont(newWord.getFont().deriveFont(Font.BOLD, 28));
        newWord.setForeground(Color.BLACK);
        newWord.setHorizontalTextPosition(JLabel.LEFT);
        newWord.setVerticalAlignment(JLabel.TOP);
        newWord.setVerticalTextPosition(JLabel.TOP);
        newWord.setBorder(BorderFactory.createEmptyBorder(445, 150, 0, 0));
        pane.add(newWord);
        frame.pack();

        frame.setLocationRelativeTo(null);
        pane.setFocusable(true);
        updateInteraction();
    }

    private void keyPress()
    {
        pane.addKeyListener(new KeyListener()
        {
            public void keyTyped(KeyEvent e) {
                for(int i = 97; i <= 122; i++){
                    //Cycles through every lowercase letter
                    if(e.getKeyChar() == (char)(i)&& pane.returnImage() == field.getImage()){
                        text += (char)(i);
                        break;
                    }
                }
                //Even in the Debugger, these next if-elses have never worked
                if(e.getKeyCode() == KeyEvent.VK_SPACE&& pane.returnImage() == field.getImage()) text += " ";
                else if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE&& pane.returnImage() == field.getImage()){
                    int x = text.length();
                    text = text.substring(0,x-1); //Not sure if this works, haven't been able to test it yet
                }
                else if(e.getKeyCode() == KeyEvent.VK_ENTER&& pane.returnImage() == field.getImage()){
                    //do something with the text
                    text = "";
                    //exit the word creator
                }
                newWord.setText(text);
                newWord.repaint(); //Apparently this isn't necessary...
            }
            public void keyPressed(KeyEvent e) {
            }
            public void keyReleased(KeyEvent e) {
            }
        }
        );
    }

    private void mouseAction()
    {
        pane.addMouseListener(new MouseListener()
        {
            public void mouseClicked(MouseEvent arg0) {
                //cover page
                if(open.contains(arg0.getPoint())&& pane.returnImage() == cover.getImage()) displayPages();
                else if(search.contains(arg0.getPoint())&& pane.returnImage() == cover.getImage()) searchWord();
                else if(enter.contains(arg0.getPoint())&& pane.returnImage() == cover.getImage()) createWord();
                //inner pages
                else if(nextPage.contains(arg0.getPoint())&& pane.returnImage() == pages.getImage()) pageFlip("next");
                else if(prevPage.contains(arg0.getPoint())&& pane.returnImage() == pages.getImage()) pageFlip("previous");
                else if(cancel.contains(arg0.getPoint())&& pane.returnImage() == field.getImage()) coverPage();
                frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
            }
            public void mouseEntered(MouseEvent arg0) {
            }
            public void mouseExited(MouseEvent arg0) {
            }
            public void mousePressed(MouseEvent arg0) {
            }
            public void mouseReleased(MouseEvent arg0) {
            }
        }
        );
    }

    private void mouseMovement()
    {
        pane.addMouseMotionListener(new MouseMotionListener()
        {
            @Override
            public void mouseMoved(MouseEvent e) {
                if(search.contains(e.getPoint())&& pane.returnImage() == cover.getImage()){
                    frame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                }
                else if(enter.contains(e.getPoint())&& pane.returnImage() == cover.getImage()){
                    frame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                }
                else if(open.contains(e.getPoint())&& pane.returnImage() == cover.getImage()){
                    frame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                }
                else if(nextPage.contains(e.getPoint())&& pane.returnImage() == pages.getImage()){
                    frame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                }
                else if(prevPage.contains(e.getPoint())&& pane.returnImage() == pages.getImage()){
                    frame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                }
                else if(cancel.contains(e.getPoint())&& pane.returnImage() == field.getImage()){
                    frame.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                }
                else{
                    frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                }
            }
            @Override
            public void mouseDragged(MouseEvent e) {
            }
        }
        );
    }

    private void updateInteraction(){
        mouseMovement();
        mouseAction();
        keyPress();
    }

    public class PaintPane extends JPanel {
        private Image background;
        private Graphics g2d;

        public PaintPane(Image image) {
            background = image;            
        }

        @Override
        public Dimension getPreferredSize() {
            return background == null ? new Dimension(0, 0) : new Dimension(background.getWidth(this), background.getHeight(this));            
        }

        @Override
        protected void paintComponent(Graphics g) {

            super.paintComponent(g);

            if (background != null) {                
                Insets insets = getInsets();

                int width = getWidth() - 1 - (insets.left + insets.right);
                int height = getHeight() - 1 - (insets.top + insets.bottom);

                int x = (width - background.getWidth(this)) / 2;
                int y = (height - background.getHeight(this)) / 2;

                g.drawImage(background, x, y, this);
            }

            //g.fillRect(654, 798, 358, 77); //for testing rectangle positioning
        }

        public Image returnImage() {
            return background;
        }
    }

私はこれを書くためにBluJを使用しています.BluJにはデバッガが組み込まれています. keyPress();createWord()の前に追加を試みupdateInteraction();、デバッガーを実行して各メソッドを段階的に実行しました。すべてが完璧に機能しました。次に、デバッガーなしで試してみましたが、入力中にテキストが表示されませんでした。というわけで、デバッガーを再度オンにしました。入力されたキーはまったく検出されませんでした。なぜそれが一度しか機能しなかったのかはわかりませんが、間違いなく機能していました. KeyListener、MouseListener、および MouseMotionListener を使用するのはこれが初めてです。このプログラムを適切に実行するためのより良い方法はありますか?

4

3 に答える 3

0

学習演習を行っているだけの場合は、JTextField を使用する代わりに独自の実装を作成してもかまいません。JPanel を呼び出してキー イベントを受信させることができますsetFocusable(true)

その後も、おそらくつまずく可能性があることに注意する必要があります。 コールバックはsのプロパティをkeyTyped入力しません。これは、関連付けられたキーが 1 つもない文字を入力できるためです。たとえば、Windows では、ALT+0160 を入力することで keyPressed を 1 回起動できます。5 つのキーを押しましたが、1 文字 (スペース) を入力し、1 つのコールバックを受け取りました。keyCodeKeyEventkeyPressed

要約 するkeyPressedと、 とkeyReleased配信され、 が配信される可能性があります。 を取得することはなく、常に を取得します。keyCodekeyCharkeyTypedkeyCodekeyChar

public class PanelKeyListener extends JFrame {

    private JPanel _contentPane;
    StringBuilder _stringBuilder = new StringBuilder();

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    PanelKeyListener frame = new PanelKeyListener();
                    frame.setSize(400, 400);
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public PanelKeyListener() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        _contentPane = new JPanel() {
            protected void paintComponent(java.awt.Graphics g) {
                g.drawString(_stringBuilder.toString(), 10, 20);
            }
        };
        setContentPane(_contentPane);
        _contentPane.setFocusable(true);
        _contentPane.addKeyListener(new KeyListener() {
            public void keyTyped(KeyEvent e) {
                System.out.println("keyTyped char[" + e.getKeyChar()
                        + "] code[" + e.getKeyCode() + "]");
                _stringBuilder.append(e.getKeyChar());
                _contentPane.repaint();
            }

            public void keyReleased(KeyEvent e) {
                System.out.println("keyReleased char[" + e.getKeyChar()
                        + "] code[" + e.getKeyCode() + "]");
            }

            public void keyPressed(KeyEvent e) {
                System.out.println("keyPressed char[" + e.getKeyChar()
                        + "] code[" + e.getKeyCode() + "]");
            }
        });
    }
}

回避できるのであれば、車輪の再発明をすべきではありません。JTextField を使用/拡張することが実用的であり、ニーズを満たしている場合。

于 2013-10-30T21:04:05.973 に答える
0

コンポーネントは、キーボード入力用にフォーカスKey Eventを持っている必要があります。ただし、動作を確認するには、まず でJPanleフォーカス可能にし ますpanel.setFocusable(true)。次にpanel.requestFocusInWindow() 、アプリケーションの起動時にフォーカスをパネルに移してみてください。

ただし、コードでは:

for(int i = 97; i <= 122; i++){
                    //Cycles through every lowercase letter
                    if(e.getKeyChar() == (char)(i)&& pane.returnImage() == field.getImage()){
                        text += (char)(i);
                        break;
                    }
                }

なぜここでループを使用する必要があるのですか? 簡単に言えば:

if(evt.getKeyChar() >=97 && evt.getKeyChar() <=122 && pane.returnImage() == field.getImage())
    text += evt.getKeyChar() 

仕事をするべきです。

于 2013-10-30T21:06:39.867 に答える