Как быстро отобразить обычную сетку?
Я хочу отобразить сетку 400 одинакового размера JPanel
s. Кажется, что обычный подход состоит в том, чтобы создать и разложить все панели, а затем фактически отобразить их. Однако в моем приложении большинство панелей изначально скрыты (например, "тральщик", но с гораздо более сложными панелями), поэтому я хотел бы иметь возможность отображать "пустую" сетку, а затем добавлять панели в это как они мне нужны. Два подхода я рассмотрел:
Избавьтесь от менеджера компоновки и просто добавьте панели с соответствующими абсолютными координатами по мере необходимости.
Используйте менеджер раскладки, но начните заполнять таблицу фиктивными компонентами и заменяйте их сложными, пока я иду.
Однако, используя любой из этих подходов, мне нужно знать размер панели заранее, чего я не знаю. Я мог бы исправить это, построив панель образцов и измерив ее, но это кажется довольно уродливым и дублирует кучу кода. Есть ли другой способ сделать это?
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);
}
}