JTextField无法在Mac OS上使用鼠标进行聚焦

时间:2017-11-29 19:29:08

标签: java macos swing jpanel

我们的任务是制作一款简单的游戏。现在,我们已经完成了很长一段时间的游戏,但我刚刚开始实现连接/主机菜单(在我们的JFrame中使用JPanel,它只包含一个用于渲染我们的精灵/形状的画布/等等。)。我们有4个JTextFields和两个JButtons。当显示该显示时,我们的画布被设置为禁用,以便不干扰输入(即,使用其鼠标监听器等)。在Windows机器上,我们可以点击所有的框,我们得到漂亮的工字梁光标等,我们可以正常输入,然后点击按钮。但是,在MacOS上尝试相同时,您无法单击框或按钮。你没有在盒子上得到工字梁。就像他们不存在一样。但是,我们可以使用tab键将焦点切换到所有元素,并可以使用它来键入框,按下按钮等,就像您应该可以使用鼠标一样。我试过像20种不同的方式请求焦点,但这似乎不起作用。我已经以相同的方式制作了许多其他应用程序(JFrame> JPanel> JButton / TextField),它们在MacOS上都运行得很好。我以前从未见过这样的事。

我不会发布一大堆整个文件,而是将其删除。第一个是我们的主要入口点,Game类。它看起来像这样:

public class Game extends Canvas implements Runnable
    private JFrame frame;
    private ConnectScreen connectScreen;
    public getFrame() { /* get reference to frame */ }
    public setFrame() { /* set the frame */ }
    public void run() { /* game loop, calls render() */ }
    public Game() { /* create window, add canvas to it, get reference to frame, instantiate stuff, etc. */ }
    public void tick() { /* every frame this happens, just tells spawners to spawn stuff, etc. */ }
    public void render() {
        BufferStrategy bs = this.getBufferStrategy();
        if (bs == null) {
            this.createBufferStrategy(3);
            return;
        }
        Graphics g = bs.getDrawGraphics();

        ///////// Draw things below this/////////////

        g.setColor(Color.black);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // SCREEN
        if (!isPaused()) {
            // THIS is where we tell the canvas to enable if we're not on the connect screen
            if (gameState != STATE.Join && gameState != STATE.Host) {
                this.setEnabled(true);
            }

            /* i omitted rendering from all of these, since it's not useful here. most say somethingScreen.render(g) or something like that. */
            if (gameState == STATE.Wave || gameState == STATE.Multiplayer || gameState == STATE.Bosses || gameState == STATE.Survival) { // render gameplay items
            } else if (gameState == STATE.Menu || gameState == STATE.Help || gameState == STATE.Credits) { // render menu
            } else if (gameState == STATE.Upgrade) { // render upgrade screen
            } else if (gameState == STATE.GameOver) { // render game over screen
            } else if (gameState == STATE.Leaderboard) { // render leaderboard
            } else if (gameState == STATE.Color) { // render color picker screen
            } else if (gameState == STATE.Join || gameState == STATE.Host) {
                // if we are on the connect screen, disable this canvas
                this.setEnabled(false);
                connectScreen.render(g);
            } else if (gameState == STATE.LeaderboardDisplay) { // render the leaderboard
            }
        } else {
            pauseMenu.render(g);
        }
        if(!isPaused()) {} // renders the handler's things
        ///////// Draw things above this//////////////
        g.dispose();
        bs.show();
    }
}

除此之外,对该课程没什么兴趣。这是(修剪过的)ConnectScreen类:

public class ConnectScreen extends JPanel {
    JFrame frame; // this is the frame from the Game class
    JTextField _____; // there are 4 of these
    JButton _____; // there are 2 of these
    public ConnectScreen(Game game) { // the game is passed in to get the frame from it
        super();
        this.setBackground(Color.black);
        this.setPreferredSize(new java.awt.Dimension(Game.WIDTH, Game.HEIGHT));
        this.setSize(new java.awt.Dimension(Game.WIDTH, Game.HEIGHT));
        this.game = game;
        this.mpSpawn = mp;
        game.getFrame().add(this);
        this.setFocusable(true);

        /* set up each component */
        /* add each component (click handlers, etc.) */
        /* add panel to frame */
    }
    public void render(Graphics g) {
        super.paintComponent(g);
        this.paintComponents(g);
    }
}

我们知道元素的设置,所有这些都有效,因为我们可以在Windows上查看和使用它们,但出于某种原因,当我们在MacOS上尝试它时,它不起作用。我们可以选择它们并键入/按下按钮,但由于某种原因,您无法单击它们进行聚焦。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

修复它,感谢MadProgrammer。显然,BufferStrategy不能用于渲染Swing组件。我刚刚在if中添加了一个Game::render()语句,如果未显示ConnectScreen,它只会进行任何渲染。如果是,它只是禁用并转动画布不可见,而ConnectScreen::render()(重命名为覆盖JPanel::paintComponent())只是使用super.paintComponent()来被动地绘制Swing组件。