简体   繁体   English

Java Swing面板分层在顶部,带有居中文本

[英]Java Swing panel layered on top with centered text

I'm making a simple Jeopardy-esque game: 我正在制作一个简单的Jeopardy-esque游戏:

在此输入图像描述

using Java Swing. 使用Java Swing。 It's obviously a JFrame with a JPanel in it and buttons in rows. 它显然是一个JFrame,其中包含JPanel和行中的按钮。

Now what I need is to add a layered panel with a centered and wrapped text in it: 现在我需要的是添加一个带有居中和包装文本的分层面板:

在此输入图像描述

Which I can remove later. 我可以在以后删除。 I already tried using JTextPane and JTextArea and JPanel, none of those want to even display. 我已经尝试过使用JTextPane和JTextArea以及JPanel,这些都不想显示。 The best effect I have achieved with AWT Panel, it does display but I can't center or wrap text in it. 我用AWT Panel实现的最佳效果,它确实显示但我不能居中或包装文本。

Here's some code for which I appologise, I would usually try to make it short and readable but since it's not working I don't know what to do with it to make ti look better: 这是我为之道歉的一些代码,我通常会尝试使其简短易读,但由于它无法正常工作,我不知道如何处理它以使其看起来更好:

    JLabel questionLabel = new JLabel(questionList.get(randomNumber).getQuestion(), SwingConstants.CENTER);
    Font font = new Font("Arial", Font.PLAIN, 20);

    //------------------JTextPane--------------------

    JTextPane questionPane = new JTextPane();
    questionPane.setForeground(Color.WHITE);
    questionPane.setSize(gameWidth, gameHeight);
    questionPane.setText(questionList.get(randomNumber).getQuestion());
    questionPane.setFont(font);
    questionPane.setEditable(false);

    //------------------AWT panel--------------------
    Panel awtPanel = new Panel();
    awtPanel.setBackground(Color.blue);
    awtPanel.setSize(game.getWidth(),game.getHeight());
    Label labelQuestion = new Label("<html>" + questionList.get(randomNumber).getQuestion() + "</html>", Label.CENTER);
    labelQuestion.setFont(font);
    awtPanel.setForeground(Color.white);

    awtPanel.add(labelQuestion);

    //------------------JPanel-----------------------
    JPanel layeredPanel = new JPanel();
    layeredPanel.setBackground(Color.blue);
    layeredPanel.setSize(game.getWidth(),game.getHeight());
    JLabel jLabelQuestion = new JLabel("<html>" + questionList.get(randomNumber).getQuestion() + "</html>", SwingConstants.CENTER);
    jLabelQuestion.setFont(font);
    layeredPanel.setForeground(Color.WHITE);

    layeredPanel.add(jLabelQuestion, BorderLayout.CENTER);

    game.getLayeredPane().add(layeredPanel, JLayeredPane.DEFAULT_LAYER);

    try {
        Thread.sleep(3000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    button.setEnabled(false);
    font = new Font("Arial", Font.PLAIN, 16);

    button.add(jLabelQuestion, BorderLayout.CENTER);
    button.setDisabledIcon(new ImageIcon(source.getScaledInstance(gameWidth/4, gameHeight/5, java.awt.Image.SCALE_SMOOTH)));

    questionList.remove(randomNumber);

    logger.info(questionList.size());

    game.getLayeredPane().remove(layeredPanel);

UPDATE: I chnaged to SWT rather than Swing, and I use the StackLayout with a few Composites in it, and just change between them as I see fit. 更新:我使用SWT而不是Swing,我在其中使用StackLayout和一些复合材料,并在我认为合适时在它们之间进行更改。

You can generally solve issues like this with a JLabel. 您通常可以使用JLabel解决此类问题。

I would recommend encapsulating the above grid in the BorderLayout.CENTER of another pane, perhaps a new content pane. 我建议将上面的网格封装在另一个窗格的BorderLayout.CENTER中,也许是一个新的内容窗格。 Then, add the caption to BorderLayout.NORTH. 然后,将标题添加到BorderLayout.NORTH。

As a more tangible example, 作为一个更切实的例子,

private void createContent() {
    this.getContentPane().setLayout(new BorderLayout());

    //establish the panel currently set as center, here labeled "everythingElse"
    this.getContentPane().add(everythingElse, BorderLayout.CENTER);

    //Create a JLabel with your caption
    JLabel jlbl = new JLabel("Question");
    //format that caption, most details being rather obvious, but most importantly:
    jlbl.setHorizontalAlignment(SwingConstants.CENTER); //keeps text centered
    this.getContentPane().add(jlbl, BorderLayout.NORTH); //add it to the top of the panel

    //...other cleanup operations...
}

The issue with grid panes is that they have a limited tolerance for the number of components visible in them. 网格窗格的问题在于它们对可见组件数量的容忍度有限。 If you overload one, it won't show. 如果你超载一个,它将不会显示。 For BorderLayout panes, you can easily swap new items into and out of them. 对于BorderLayout窗格,您可以轻松地将新项目交换进出。

For efficiency's sake, I might recommend compiling this JLabel as a final somewhere else in your code, and holding onto it for when you need it. 为了提高效率,我可能会建议将此JLabel编译为代码中的其他位置,并在需要时保留它。 This way, you will also dodge overhead from repeatedly creating the label object. 这样,您也可以避免重复创建标签对象。

Lastly, avoid AWT whenever you can. 最后,尽可能避免使用AWT。 It's been deprecated for an excess of ten years, and if you do use it you will run into numerous critical problems involving heavyweight and lightweight component incompatibilities. 它被弃用了超过十年,如果你使用它,你将遇到许多涉及重量级和轻量级组件不兼容的关键问题。 If you intend to use another windowing kit, consider implementing the new standard, JavaFX, with a JFXPane-- it's much more tolerant of HTML syntax, as well. 如果您打算使用另一个窗口工具包,请考虑使用JFXPane实现新标准JavaFX--它也更容忍HTML语法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM