Как быстро отобразить обычную сетку?

Я хочу отобразить сетку 400 одинакового размера JPanels. Кажется, что обычный подход состоит в том, чтобы создать и разложить все панели, а затем фактически отобразить их. Однако в моем приложении большинство панелей изначально скрыты (например, "тральщик", но с гораздо более сложными панелями), поэтому я хотел бы иметь возможность отображать "пустую" сетку, а затем добавлять панели в это как они мне нужны. Два подхода я рассмотрел:

  1. Избавьтесь от менеджера компоновки и просто добавьте панели с соответствующими абсолютными координатами по мере необходимости.

  2. Используйте менеджер раскладки, но начните заполнять таблицу фиктивными компонентами и заменяйте их сложными, пока я иду.

Однако, используя любой из этих подходов, мне нужно знать размер панели заранее, чего я не знаю. Я мог бы исправить это, построив панель образцов и измерив ее, но это кажется довольно уродливым и дублирует кучу кода. Есть ли другой способ сделать это?

2 ответа

Используйте шаблон flyweight для визуализации только видимых панелей. Подход иллюстрируется в JTable рендеры и обрисованы в общих чертах здесь.

Я бы не стал использовать панно или нестандартную живопись здесь. Вместо:

  • Составная часть: JToggleButton
  • Планировка: GridLayout
  • плитки: Icon (стандартный, сфокусированный, нажатый, выбранный и т. д.)

НАПРИМЕР

import java.awt.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

class MineSweeper {

    public static final int COLS = 20;
    public static final int ROWS = 20;

    public static void main(String[] args) throws Exception {
        URL urlDefault = new URL("https://stackru.com/images/1f6d2ebcbd4f5de48a6c04aaabe3403f8d7b0381.png");
        URL urlPressed = new URL("https://stackru.com/images/f69f1ea3625c9477130c9067af102811460b7092.png");
        URL urlSelected = new URL("https://stackru.com/images/94bfe1ea4270e89c546f3eb8d0ebc0329500e104.png");
        final Image imgDefault = ImageIO.read(urlDefault);
        final Image imgPressed = ImageIO.read(urlPressed);
        final Image imgSelected = ImageIO.read(urlSelected);
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JPanel gui = new JPanel(new GridLayout(ROWS, COLS, 2, 2));
                ImageIcon iiDefault = new ImageIcon(imgDefault);
                for (int ii = 0; ii < COLS; ii++) {
                    for (int jj = 0; jj < ROWS; jj++) {
                        JToggleButton tb = new JToggleButton(iiDefault);
                        tb.setContentAreaFilled(false);
                        tb.setMargin(new Insets(0,0,0,0));
                        tb.setPressedIcon(new ImageIcon(imgPressed));
                        tb.setSelectedIcon(new ImageIcon(imgSelected));
                        gui.add(tb);
                    }
                }

                JOptionPane.showMessageDialog(null, gui);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}
Другие вопросы по тегам