JPanel占用了整个JFrame

时间:2015-05-15 21:29:44

标签: java jframe jpanel

我有一个问题,当我在我的JFrame中包含JPanel时,它会覆盖整个屏幕。我的代码是

import java.awt.*;

import javax.swing.*;

public class TestFrameExample extends JPanel {

    static String TheQuestion;
    static String QN1 = "Question 1: ";

    static String Q1 = "What is Lead's chemical symbol?";

    static String brk = "___________________";

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        this.setBackground(new Color(135, 206, 250));

        g.setFont(new Font("Tahoma", Font.BOLD, 48));
        g.setColor(Color.WHITE);
        g.drawString(QN1, 80, 100);

        g.setFont(new Font("Tahoma", Font.BOLD, 48));
        g.setColor(Color.WHITE);
        g.drawString(brk, 60, 130);

        g.setFont(new Font("Tahoma", Font.PLAIN, 36));
        g.setColor(Color.WHITE);
        g.drawString(Q1, 80, 200);
    }



    public static void main(String[] args) {

        TestFrameExample graphics = new TestFrameExample();
        JFrame ThisFrame = new JFrame();

        TheQuestion = QN1;

        JTextField txt = new JTextField(10);
        JPanel Panel = new JPanel();

        ThisFrame.setTitle("Question 1");
        ThisFrame.setSize(720, 480);
        ThisFrame.setLocationRelativeTo(null);
        ThisFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ThisFrame.setVisible(true);
        ThisFrame.add(graphics);

        Panel.setBackground(new Color(135, 206, 250));
        Panel.setSize(null);
        Panel.setLocation(null);
        Panel.add(txt);
        ThisFrame.add(Panel);

    }
}

然而,当我改变

Panel.setLocation(null)

Panel.setLocation(80, 250)

它涵盖了整个屏幕。

有人可以帮我把它放在屏幕上的正确位置吗?

更新

我按照我在评论中所说的那样进行了修改,代码为

import java.awt.*;
import javax.swing.*;

public class TestFrameExample extends JPanel {

static String TheQuestion;
static String QN1 = "Question 1: ";

static String Q1 = "What is Lead's chemical symbol?";

static String brk = "___________________";

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.setBackground(new Color(135, 206, 250));

    g.setFont(new Font("Tahoma", Font.BOLD, 48));
    g.setColor(Color.WHITE);
    g.drawString(QN1, 80, 100);

    g.setFont(new Font("Tahoma", Font.BOLD, 48));
    g.setColor(Color.WHITE);
    g.drawString(brk, 60, 130);

    g.setFont(new Font("Tahoma", Font.PLAIN, 36));
    g.setColor(Color.WHITE);
    g.drawString(Q1, 80, 200);
}



public static void main(String[] args) {

    TestFrameExample graphics = new TestFrameExample();
    JFrame ThisFrame = new JFrame();

    TheQuestion = QN1;

    JTextField txt = new JTextField(20);
    JPanel panel = new JPanel();

    ThisFrame.setTitle("Question 1");
    ThisFrame.setSize(720, 480);
    ThisFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ThisFrame.add(graphics);

    panel.setBackground(new Color(135, 206, 250));
    panel.add(txt);
    ThisFrame.add(panel);
    ThisFrame.add(panel, BorderLayout.PAGE_END);

    ThisFrame.setLocationRelativeTo(null);
    ThisFrame.setVisible(true);

}
}

它将输入txt放在屏幕的底部,但屏幕的其余部分仍为灰色。

但我根本不理解您发布的第二组代码;它远远超出了我的技能(我过去6周才学习Java)。我在这个阶段所寻找的只是使面板不会在屏幕的其余部分显示为空白。

这可以通过修改当前的代码集来实现,还是必须完全重写代码?

1 个答案:

答案 0 :(得分:4)

默认情况下,JFrame的contentPane使用BorderLayout,您可以使用它:

  • 将您的TestFrameExample对象BorderLayout.CENTER添加到您的JFrame
  • 将您的其他JPanel或JTextField添加到BorderLayout.PAGE_END位置的JFrame。这会将组件添加到GUI的底部。
  • 请不要在您的组件上调用setLocation(...),因为它邀请使用null布局,这种布局会导致难以调试的严格图形用户界面升级。

有关详细信息,请阅读教程中的BorderLayout。

如,

public static void main(String[] args) {
    TestFrameExample graphics = new TestFrameExample();
    JFrame thisFrame = new JFrame();

    TheQuestion = QN1;

    JTextField txt = new JTextField(10);
    JPanel panel = new JPanel();

    thisFrame.setTitle("Question 1");
    thisFrame.setSize(720, 480); // better to not do this, but to pack instead
    // thisFrame.setLocationRelativeTo(null);
    thisFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // thisFrame.setVisible(true); // *** not yet ***
    thisFrame.add(graphics, BorderLayout.CENTER);

    panel.setBackground(new Color(135, 206, 250));
    // panel.setSize(null); // *** don't do this ***
    // panel.setLocation(null); // *** don't do this ***
    panel.add(txt);
    thisFrame.add(panel, BorderLayout.PAGE_END);

    thisFrame.setLocationRelativeTo(null);
    thisFrame.setVisible(true); // *** HERE ***

}

请注意,我自己,如果可能的话,我会避免直接绘画,而是使用组件和布局管理器。这样可以更容易地显示不同类型的问题。例如,运行以下程序并反复按<enter>键,滚动问题以查看我的意思:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

public class TestQuestion2 extends JPanel {
   private static final Color BACKGROUND = new Color(135, 206, 250);
   private static final Color LABEL_FOREGROUND = Color.white;
   private static final int EB_GAP = 60;
   private static final int PREF_W = 720;
   private static final int PREF_H = 480;
   private static final Font TITLE_FONT = new Font("Tahoma", Font.BOLD, 48);
   private static final Font Q_FONT = TITLE_FONT.deriveFont(Font.PLAIN, 36f);
   private JLabel questionTitleLabel = new JLabel();
   private JTextArea questionArea = new JTextArea(4, 10);
   private JTextField answerField = new JTextField(20);
   private Question question;
   private List<Question> questionList;
   private int questionListIndex = 0;

   public TestQuestion2(List<Question> questionList) {
      this.questionList = questionList;
      questionTitleLabel.setFont(TITLE_FONT);
      questionTitleLabel.setForeground(LABEL_FOREGROUND);
      JSeparator separator = new JSeparator();
      separator.setForeground(LABEL_FOREGROUND);

      questionArea.setFont(Q_FONT);
      questionArea.setForeground(LABEL_FOREGROUND);
      questionArea.setWrapStyleWord(true);
      questionArea.setLineWrap(true);
      questionArea.setBorder(null);
      questionArea.setOpaque(false);
      questionArea.setFocusable(false);
      JScrollPane scrollPane = new JScrollPane(questionArea);
      scrollPane.setBorder(null);
      scrollPane.setOpaque(false);
      scrollPane.getViewport().setOpaque(false);

      JPanel answerPanel = new JPanel();
      answerPanel.add(answerField);
      answerPanel.setOpaque(false);

      setBackground(BACKGROUND);
      setBorder(BorderFactory.createEmptyBorder(EB_GAP, EB_GAP, EB_GAP, EB_GAP));
      setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      add(questionTitleLabel);
      add(Box.createHorizontalStrut(10));
      add(separator);
      add(Box.createHorizontalStrut(5));
      add(scrollPane);
      add(Box.createHorizontalGlue());
      add(answerPanel);

      setQuestion(questionList.get(questionListIndex));

      answerField.addActionListener(new AnswerListener());
   }

   public void setQuestion(Question question) {
      this.question = question;
      questionTitleLabel.setText("Question " + question.getNumber() + ":");
      questionArea.setText(question.getQuestion());
   }

   @Override
   public Dimension getPreferredSize() {
      Dimension superSz = super.getPreferredSize();
      if (isPreferredSizeSet()) {
         return superSz;
      }
      int prefW = Math.max(superSz.width, PREF_W);
      int prefH = Math.max(superSz.height, PREF_H);
      return new Dimension(prefW, prefH);
   }

   private class AnswerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         questionListIndex++;
         questionListIndex %= questionList.size();
         setQuestion(questionList.get(questionListIndex));
      }
   }

   private static void createAndShowGui() {
      List<Question> questionList = new ArrayList<>();
      questionList.add(new Question(1, "What is Lead's chemical symbol?"));
      questionList.add(new Question(2, "Who is buried in Grant's tomb?"));
      questionList.add(new Question(3, "What ..... is your quest?"));
      questionList.add(new Question(4, "What ..... is your favorite color?"));
      questionList.add(new Question(5, "What is the capital of Assyria?"));
      questionList.add(new Question(6, "What is the airspeed velocity of the unladen laden swallow?"));
      questionList.add(new Question(7, "This will be a very long question, one that shows the display "
            + "of multiple lines, and a JTextArea that looks like a JLabel. "
            + "What do you think of it?"));

      TestQuestion2 testQuestion2Panel = new TestQuestion2(questionList);

      JFrame frame = new JFrame("Question");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(testQuestion2Panel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class Question {
   private int number;
   private String question;
   private List<String> possibleAnswers;

   public Question(int number, String question) {
      this.number = number;
      this.question = question;
   }
   public int getNumber() {
      return number;
   }
   public void setNumber(int number) {
      this.number = number;
   }
   public String getQuestion() {
      return question;
   }
   public void setQuestion(String question) {
      this.question = question;
   }
}