Вопрос по jpanel, swing, java, user-interface – Оконная рама, покрывающая графический контент

3

это мой первый пост здесь, и у меня есть вопрос, который кажется очень странным, но это беспокоило меня в течение последнего часа или около того.

Я делаю простой JFrame с JPanel в нем, но рамка Windows 7, по-видимому, блокирует мой вид частей панели. Например, если я нарисую маленький квадрат с координатой 0,0, он не появится, и я подозреваю, что он находится за рамкой окна.

Я пытался поэкспериментировать с пакетом, размерами, заданным размером, размерами и разными макетами, но не могу отобразить верхние 20 пикселей или около того!

Вот что у меня есть:

public RedSunGame() {
super("Red Sun");

rs = new JPanel(new BorderLayout(), true);
rs.setPreferredSize(new Dimension(WIDTH, HEIGHT));
add(rs, "Center");

setPreferredSize(new Dimension(WIDTH, HEIGHT));
pack();
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}

EDIT:

Спасибо за все ваши ответы, извините за отсутствие информации :)

Я использую стратегию двойного буфера, которую я видел в книге. gameRender и paintScreen находятся в стандартном игровом цикле. Мой класс RedSunGame расширяет JFrame. Весь соответствующий код вы можете запросить в дополнение к выше:

private static final int WIDTH = 500;
private static final int HEIGHT = 500;
private JPanel rs;
private Graphics2D g2d;
private Image dbImage;

private void gameRender() {
//create buffer
if (dbImage == null){
  dbImage = createImage(WIDTH, HEIGHT);
  g2d = (Graphics2D)dbImage.getGraphics();
}
//clear screen
g2d.setColor(Color.white);
g2d.fillRect(0, 0, WIDTH, HEIGHT);

g2d.setColor(Color.blue);
g2d.setFont(font);
g2d.drawString("FPS: " + FPS, 0, HEIGHT);
g2d.fillRect(30, 30, 10, 10);
}

private void paintScreen() {
Graphics g;
try {
  g = getGraphics();
  if ((g != null) && (dbImage != null))
    g.drawImage(dbImage, 0, 0, null);
  Toolkit.getDefaultToolkit().sync();
  g.dispose();
}
catch (Exception e)
{ System.out.println("Graphics context error: " + e);  }
}

С моими текущими настройками это выглядит так. http://i.imgur.com/qaabC.png

Это то, что происходит, если у меня есть g2d.fillRect (30, 30, 10, 10), единственное изменение - координаты 30,30 вместо 0,0. Это определенно скрывается за границей наверху. http://i.imgur.com/uzfFe.png

Кроме того, установка его в BorderLayout.CENTER, похоже, не имеет значения в любом из этих случаев.

(извините, но новые пользователи не могут публиковать изображения)

EDIT: Я понял. Я рисовал прямо в JFrame. @Guillaume Polet Я понимаю, почему вы не должны переопределять метод рисования JFrames, поскольку он рисует в кадре, а не на панели, которая должна отображать содержимое !! Спасибо

Код, который вы разместили, не показывает, где вы рисуете свой маленький квадрат. Guillaume Polet
Скриншот объяснит гораздо понятнее слов ... Thihara
Просто предложение, никогда не пытайтесь использоватьsetXxXSize(...) методы, так как многиеLayout Managers не соблюдайте пользовательские значения размера. Пусть заинтересованныеLayout Manager позаботьтесь о размере компонента. Просто добавив компонент в ЦЕНТРBorderLayout сделает свое дело для вашего случая, как описано в каждом ответе :-) nIcE cOw

Ваш Ответ

3   ответа
1

Попробуй это:

//add(rs, "center");
add(rs, BorderLayout.CENTER);
0

но для новичка в java swing я предлагаю вам воспользоваться Net-beans IDE. он графически добавляет и размещает графический интерфейс, и вам не нужно писать какой-либо рукописный код. Это отличное место для начала, как указано здесь:

http://docs.oracle.com/javase/tutorial/uiswing/learn/index.html

Я бы рекомендовал прямо противоположное: сначала освоите Swing «вручную», а затем используйте GUI-компоновщики, когда вы знаете, что делаете. Многие вопросы, возникающие в связи с SO, связаны с тем, что люди используют GUI-конструктор и вообще не понимают, что делает Swing.
3

который показывает, как ваша цель может быть достигнута. Попробуйте найти различия в вашем коде, чтобы понять, что не так:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class RedSunGame {

    private static final int SQUARE_SIZE = 20;
    private JPanel rs;
    private JFrame frame;

    private void initUI() {
        frame = new JFrame("Red Sun");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        rs = new JPanel(new BorderLayout()) {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.YELLOW);
                g.fillRect(0, 0, SQUARE_SIZE, SQUARE_SIZE);
            }

            @Override
            public Dimension getPreferredSize() {
                Dimension preferredSize = super.getPreferredSize();
                // Let's make sure that we have at least our little square size.
                preferredSize.width = Math.max(preferredSize.width, SQUARE_SIZE);
                preferredSize.height = Math.max(preferredSize.height, SQUARE_SIZE);
                return preferredSize;
            }
        };
        frame.add(rs);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                RedSunGame redSunGame = new RedSunGame();
                redSunGame.initUI();
            }
        });
    }
}
+1 за переопределениеgetPreferredSize().
Есть много проблем с вашим кодом. Я не знаю, переопределите ли выpaint метод JFrame, но если вы это сделаете: не делайте! ;-), сделайте это на ContentPane или других дочерних компонентах. Теперь, для вашего кода, вы почти никогда не должны звонитьgetGraphics и вы никогда не должны иметь ссылку наGraphics, Либо вы используете предоставленный в качестве параметра методов paintXXX (), либо создаете свой собственный (например, в BufferedImage, вы можете вызвать createGraphics, нарисовать, а затем утилизировать графику). Что касается двойной буферизации, то она по умолчанию включена в Swing, поэтому не делайте это самостоятельно во второй раз.
Если я перезаписываю paintComponent в своем коде, как вы, он работает и рисует желтый квадрат в углу, но по какой-то причине он не работает с буфером, который я создал. Есть идеи? Mike

Похожие вопросы