Только пользовательский JComponent Отображается на JFrame, а не на JPanel - PullRequest
2 голосов
/ 02 февраля 2012

Может кто-нибудь помочь мне понять, почему мой пользовательский JComponent 'Bar' отображается только при добавлении непосредственно в JFrame, а не при добавлении в JPanel (который затем добавляется в JFrame)?

Спасибо!

package main;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Board {

    public void start(){
        JFrame frame = new JFrame();
        JButton button1 = new JButton("Button 1");
        Bar statusbar = new Bar();
        JLabel status = new JLabel("Status: ");

        JPanel topPanel = new JPanel();
        topPanel.add(status);
        topPanel.add(statusbar);

        JPanel mainPanel = new JPanel();
        mainPanel.add(button1);
        mainPanel.add(statusbar);

        frame.getContentPane().add(BorderLayout.NORTH, topPanel);
        frame.getContentPane().add(BorderLayout.SOUTH, mainPanel);
        frame.getContentPane().add(BorderLayout.CENTER, statusbar);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(200,100);
        frame.setVisible(true);
    }
}

Вот мой класс бар ...

package main;

import java.awt.Graphics;

import javax.swing.JComponent;

public class Bar extends JComponent{
    public void paint(Graphics g){
        g.fillRect(0, 0, 100, 10);
    }
}

Ответы [ 2 ]

3 голосов
/ 02 февраля 2012

Размер пользовательского компонента: (0, 0).

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

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

Это объясняет, почему пользовательский компонент отображается только при добавлении непосредственно в JFrame, поскольку он использует менеджер компоновки BorderLayout, тогда какJPanel использует менеджер компоновки FlowLayout.

3 голосов
/ 02 февраля 2012

Вы добавляете statusbar в несколько различных мест в дереве компонентов, Swing плохо с этим справляется (или вообще).

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

Редактировать

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

Попробуйте:

public static class Bar extends JComponent {

    private Bar() {
        setPreferredSize(new Dimension(25, 5));
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(0, 0, 100, 10);
    }
}

Вы также должны добавить frame.pack() перед отображением.

(множественные ссылки на один и тот же компонент тоже верны)

...