2015-07-18 8 views
0

Я хочу разместить JPanel с размером 300,200 на месте 100,50 в JFrame, но следующий код делает весь JFrame заполненным JPanel, где я ошибаюсь? Код:JPanel заполнить весь JFrame

public class Class1 { 

    public static void main(String[] args) { 

     JFrame frame = new JFrame(); 
     JPanel panel = new JPanel(); 

     frame.setSize(700, 500);    
     panel.setSize(300, 200); 
     panel.setBackground(Color.green); 
     panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR)); 

     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     frame.add(panel, BorderLayout.CENTER);   

     frame.setVisible(true); 
     frame.setLocationRelativeTo(null); 
    } 


} 

Если изменить BorderLayout.SOUTH или север, JPanel выглядит как тонкая линия в нижней или верхней части JFrame. Также я попытался использовать предпочтительный размер, но все тот же результат.

+6

Прочтите руководства по менеджерам макетов Swing, чтобы узнать, почему это происходит. Поймите, что JFrame (на самом деле его contentPane) использует BorderLayout по умолчанию. Также знайте, что большинство менеджеров макетов не уважают размер компонентов, а предпочитают их размеры. Также знайте, что если вы используете макет «null», вы нарисуете себя в углу; поэтому избегайте их. –

+0

Что содержит панель, которая бы сделала размер '300 x 200'? Что содержит ферма, которая делает панель, отображаемую в '100, 50'? – trashgod

+0

Я боюсь, что приведенные ответы не помогут понять, как работают макетные менеджеры. Они будут только путать его дальше. Нет такой вещи, как плохой студент, только плохой учитель – Constantin

ответ

4

Вам необходимо понять основы менеджеров макетов, прежде чем вы сможете попробовать что-либо с Swing.

Изучение учебник здесь https://docs.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html

Если вы пытаетесь построить форму с различными элементами управления Качели, никогда не использовать абсолютные координаты для размещения их. Изменение размера окна должно динамически перемещать элементы управления в соответствии с типом макета, который вы хотите использовать. Если вы используете панель в качестве холста для рисования (что, как я думаю, вам нужно), посмотрите на мой пример ниже.

Попытайтесь сначала освоить пару фундаментальных макетов, таких как BorderLayout и GridLayout. После освоения вы можете использовать очень мало, чтобы достичь практически любого желаемого макета, вложив их вместе. Также изучите основы ScrollPane, чтобы эффективно использовать экранную недвижимость

Что касается вашего первоначального вопроса, я создал пример того, как работает BorderLayout и как рисовать в определенном регионе на панели. Я также добавил код, чтобы вы могли установить свой курсор по-разному в зависимости от того, находитесь ли вы в меньшей области внутри данной панели.

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

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Cursor; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionListener; 

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

public class FrameDemo extends JFrame { 
    private static final long serialVersionUID = 1L; 

    public FrameDemo() { 
    super("Frame Demo"); 
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

    getContentPane().add(new CustomPanel(Color.RED), BorderLayout.NORTH); 
    getContentPane().add(new CustomPanel(Color.GREEN), BorderLayout.SOUTH); 
    getContentPane().add(new CustomPanel(Color.BLUE), BorderLayout.EAST); 
    getContentPane().add(new CustomPanel(Color.YELLOW), BorderLayout.WEST); 
    getContentPane().add(new JScrollPane(new CustomPanel(Color.BLACK)), BorderLayout.CENTER); 

    pack(); 
    } 

    public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     JFrame frame = new FrameDemo(); 
     frame.setVisible(true); 
     } 
    }); 
    } 
} 

class CustomPanel extends JPanel implements MouseMotionListener { 
    private static final long serialVersionUID = 1L; 

    private static final Dimension PANEL_SIZE = new Dimension(200, 100); 
    private static final int HAND_CURSOR_INDEX = 1; 
    private static final int DEFAULT_CURSOR_INDEX = 0; 
    private static final Cursor[] _cursors = new Cursor[] { 
    Cursor.getDefaultCursor(), 
    Cursor.getPredefinedCursor(Cursor.HAND_CURSOR) 
    }; 

    // I want to place a JPanel with 300,200 size at 100,50 location in a JFrame 
    private static final Rectangle _rectangle = new Rectangle(50, 10, 40, 50); 

    public CustomPanel(Color color) { 
    setBackground(color); 
    addMouseMotionListener(this); 
    } 

    public Dimension getPreferredSize() { 
    return PANEL_SIZE; 
    } 

    public Dimension getMinimumSize() { 
    return PANEL_SIZE; 
    } 

    public Dimension getMaximumSize() { 
    return PANEL_SIZE; 
    } 


    protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.setColor(Color.WHITE); 
    g.fillRect(
     (int)_rectangle.getX(), 
     (int)_rectangle.getY(), 
     (int)_rectangle.getWidth(), 
     (int)_rectangle.getHeight()); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
    // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
    int cursorIndex = _rectangle.contains(e.getPoint()) ? 
     HAND_CURSOR_INDEX : 
     DEFAULT_CURSOR_INDEX; 
     setCursor(_cursors[cursorIndex]); 
    } 
} 

enter image description here

1

Если вы хотите, чтобы панель оккупировать часть JFrame (ContentPane) вы можете использовать другие менеджеры компоновки. Он является примером использования GroupLayout:

import java.awt.Color; 
import java.awt.Cursor; 
import java.awt.Dimension; 

import javax.swing.GroupLayout; 
import javax.swing.GroupLayout.Alignment; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.WindowConstants; 

public class Class1 { 

    public static void main(String[] args) { 

     JFrame frame = new JFrame(); 
     JPanel panel = new JPanel(); 

     frame.getContentPane().setPreferredSize(new Dimension(700, 500)); 
     panel.setPreferredSize(new Dimension(300, 200)); 
     panel.setBackground(Color.green); 
     panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR)); 

     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     GroupLayout groupLayout = new GroupLayout(frame.getContentPane()); 
     groupLayout.setHorizontalGroup(
      groupLayout.createParallelGroup(Alignment.LEADING) 
       .addGroup(groupLayout.createSequentialGroup() 
        .addGap(104) 
        .addComponent(panel, GroupLayout.PREFERRED_SIZE, 493, GroupLayout.PREFERRED_SIZE) 
        .addContainerGap(103, Short.MAX_VALUE)) 
     ); 
     groupLayout.setVerticalGroup(
      groupLayout.createParallelGroup(Alignment.LEADING) 
       .addGroup(groupLayout.createSequentialGroup() 
        .addGap(100) 
        .addComponent(panel, GroupLayout.PREFERRED_SIZE, 301, GroupLayout.PREFERRED_SIZE) 
        .addContainerGap(99, Short.MAX_VALUE)) 
     ); 
     frame.getContentPane().setLayout(groupLayout); 
     frame.pack(); 
     frame.setVisible(true); 
     frame.setLocationRelativeTo(null); 
    } 


} 

выход: enter image description here

Другой пример использования BorderLayout с 4 дополнительными "место держатель" или копирующих панелей:

import java.awt.Color; 
import java.awt.Cursor; 
import java.awt.Dimension; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.WindowConstants; 
import java.awt.BorderLayout; 

public class Class1 { 

    public static void main(String[] args) { 

     JFrame frame = new JFrame(); 

     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     frame.getContentPane().setLayout(new BorderLayout(0, 0)); 

     JPanel centerPanel = new JPanel(); 
     centerPanel.setPreferredSize(new Dimension(300, 200)); 
     centerPanel.setBackground(Color.green); 
     centerPanel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR)); 
     frame.getContentPane().add(centerPanel); 

     JPanel northPanel = new JPanel(); 
     northPanel.setBackground(Color.RED); 
     northPanel.setForeground(Color.BLACK); 
     northPanel.setPreferredSize(new Dimension(0, 150)); 
     frame.getContentPane().add(northPanel, BorderLayout.NORTH); 

     JPanel westPanel = new JPanel(); 
     westPanel.setBackground(Color.MAGENTA); 
     westPanel.setPreferredSize(new Dimension(200, 0)); 
     frame.getContentPane().add(westPanel, BorderLayout.WEST); 

     JPanel southPanel = new JPanel(); 
     southPanel.setBackground(Color.YELLOW); 
     southPanel.setPreferredSize(new Dimension(0, 150)); 
     frame.getContentPane().add(southPanel, BorderLayout.SOUTH); 

     JPanel eastPanel = new JPanel(); 
     eastPanel.setBackground(Color.BLUE); 
     eastPanel.setPreferredSize(new Dimension(200, 0)); 
     frame.getContentPane().add(eastPanel, BorderLayout.EAST); 

     frame.pack(); 
     frame.setVisible(true); 
     frame.setLocationRelativeTo(null); 
    } 


} 

выход: enter image description here

+0

Учитывая беспорядок пута об основах менеджеров макетов, вы действительно думаете, что ваш код действительно поможет ему туда добраться? Давайте попробуем понять, чего он пытается достичь, иначе вы будете путать его еще больше, чем он уже есть :) – Constantin

+0

Thnks для комментария @ Константин, На мой взгляд, примеры - лучший способ прояснить. Это работает для меня лучше, чем любая документация или объяснение. Давайте посмотрим (0: – c0der

+0

Ваш второй пример намного лучше: использование сложных менеджеров компоновки совершенно не нужно. Я могу создать самые сложные макеты, просто используя BorderLayout и GridLayout, вложенные в них, но для этого требуется полное мастерство. понимает теорию, стоящую за ними. – Constantin

1
import javax.swing.*; 
import java.awt.*; 
public class Class1 { 

    public static void main(String[] args) { 

     JFrame frame = new JFrame(); 
     JPanel panel = new JPanel(); 
     JPanel another = new JPanel(); 
     JPanel emptyPanel = new JPanel(); 
     emptyPanel.setPreferredSize(new Dimension(700, 50)); 
     frame.setSize(700, 500); 


     panel.setMaximumSize(new Dimension(300, 200)); 
     panel.setMinimumSize(new Dimension(300, 200)); 
     panel.setPreferredSize(new Dimension(300, 200)); 
     panel.setBackground(Color.green); 
     panel.setCursor(new Cursor(java.awt.Cursor.HAND_CURSOR)); 

     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     another.add(emptyPanel, BorderLayout.NORTH); 
     another.add(panel, BorderLayout.CENTER);   

     frame.add(another); 
     frame.setVisible(true); 
     frame.setLocationRelativeTo(null); 
    } 


} 

Созданное изображение выглядит ниже enter image description here

Мне кажется, что непосредственный дочерний контейнер JFrame изменен до размера самого JFrame, самого контейнера верхнего уровня.

+1

Если op фактически пытается разместить элементы управления Swing на форме, что маловероятно, этот подход будет делать трюк и является правильным ответом. Если, однако, op пытается что-то нарисовать конкретный регион на экране, ваш пример, безусловно, не правильный подход. Если оп объясняет, каково его намерение, мы не можем знать – Constantin

 Смежные вопросы

  • Нет связанных вопросов^_^