java 在 JFrame 中绘制网格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36380516/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Drawing a grid in a JFrame
提问by xZeasy
i have a 9x9 grid of buttons right now, and i would like to draw some lines between those buttons to separate them and make a 3x3 grid.
我现在有一个 9x9 的按钮网格,我想在这些按钮之间画一些线来分隔它们并制作一个 3x3 网格。
I tried my method in a JPanel in another window and it works fine, but i can't get it work in my JFrame alongside my buttons, as it draws nothing. There is already some space between each button so we can see the line if it's there.
我在另一个窗口的 JPanel 中尝试了我的方法,它工作正常,但我无法在我的 JFrame 中与我的按钮一起工作,因为它什么也没画。每个按钮之间已经有一些空间,所以我们可以看到它在那里的线。
Thanks a lot for your future help.
非常感谢您未来的帮助。
Here is the code :
这是代码:
import javax.swing.*;
import java.awt.*;
public class ButtonGrid extends JPanel{
JFrame frame=new JFrame();
int t = 9;
public ButtonGrid(){ //constructor
frame.setLayout(new GridLayout(t, t, 3, 3));
addButtons(frame, t);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
@Override public void paint(Graphics g) {
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
for (int i = 0; i <= 9; i++) {
if (i % 3 == 0) {
int coord = i * 58;
coord++;
g.drawLine(coord, 0, coord, 58*9);
g.drawLine(0, coord, 58*9, coord);
}
}
}
private void addButtons(JFrame frame, int t){
JButton grid;
for(int y=0; y<t; y++){
for(int x=0; x<t; x++){
grid=new JButton(x+","+y); //creates new button
grid.setPreferredSize(new Dimension(55,55));
frame.add(grid); //adds button to grid
}
}
}
public static void main(String[] args) {
new ButtonGrid();
}
}
}
回答by Hovercraft Full Of Eels
Never draw directly on the JFrame as you're trying to do. This carries significant risk if you don't know what you're doing (for example you don't call the super's paint method and are inadvertently breaking the painting chain this way), and the images drawn won't show as they'll be covered by the opaque contentPane.
切勿像您尝试那样直接在 JFrame 上绘图。如果您不知道自己在做什么(例如,您没有调用 super 的paint 方法并且以这种方式无意中破坏了绘画链),这会带来很大的风险,并且绘制的图像不会像它们那样显示被不透明的 contentPane 覆盖。
If you need to draw, do so in a JPanel that is then displayed inside the JFrame, but again as per my example below, there's no need to draw if all you want are black straight lines in a grid.
如果您需要绘制,请在 JFrame 内显示的 JPanel 中进行绘制,但同样按照我下面的示例,如果您想要的只是网格中的黑色直线,则无需绘制。
Use a GridLayout, and set some gaps into your layout. Understand that the 3rd and 4th parameters of the GridLayout constructor will give you the gaps. Then give the underlying JPanel a Color.BLACK background, and there you go: lines! For example with JTextFields:
使用 GridLayout,并在布局中设置一些间隙。了解 GridLayout 构造函数的第 3 个和第 4 个参数会给您带来差距。然后给底层的 JPanel 一个 Color.BLACK 背景,然后你去:线条!例如使用 JTextFields:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SudokuMCVE extends JPanel {
private static final int CLUSTER = 3;
private static final int MAX_ROWS = 9;
private static final float FIELD_PTS = 32f;
private static final int GAP = 3;
private static final Color BG = Color.BLACK;
private static final Color SOLVED_BG = Color.LIGHT_GRAY;
public static final int TIMER_DELAY = 2 * 1000;
private JTextField[][] fieldGrid = new JTextField[MAX_ROWS][MAX_ROWS];
public SudokuMCVE() {
JPanel mainPanel = new JPanel(new GridLayout(CLUSTER, CLUSTER));
mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.setBackground(BG);
JPanel[][] panels = new JPanel[CLUSTER][CLUSTER];
for (int i = 0; i < panels.length; i++) {
for (int j = 0; j < panels[i].length; j++) {
panels[i][j] = new JPanel(new GridLayout(CLUSTER, CLUSTER, 1, 1));
panels[i][j].setBackground(BG);
panels[i][j].setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.add(panels[i][j]);
}
}
for (int row = 0; row < fieldGrid.length; row++) {
for (int col = 0; col < fieldGrid[row].length; col++) {
fieldGrid[row][col] = createField(row, col);
int i = row / 3;
int j = col / 3;
panels[i][j].add(fieldGrid[row][col]);
}
}
setLayout(new BorderLayout());
add(mainPanel, BorderLayout.CENTER);
add(new JButton(new SolveAction("Solve")), BorderLayout.PAGE_END);
}
private JTextField createField(int row, int col) {
JTextField field = new JTextField(2);
field.setHorizontalAlignment(JTextField.CENTER);
field.setFont(field.getFont().deriveFont(Font.BOLD, FIELD_PTS));
return field;
}
private class SolveAction extends AbstractAction {
public SolveAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
new Timer(TIMER_DELAY, new ActionListener() {
private int i = 0;
private int j = 0;
@Override
public void actionPerformed(ActionEvent e) {
// MAX_ROWS is 9
if (i == MAX_ROWS) {
((Timer) e.getSource()).stop();
}
if (j == MAX_ROWS) {
i++;
j = 0;
}
int number = (int) (MAX_ROWS * Math.random()) + 1;
fieldGrid[i][j].setBackground(SOLVED_BG);
fieldGrid[i][j].setText(String.valueOf(number));
j++;
}
}).start();
}
}
private static void createAndShowGui() {
SudokuMCVE mainPanel = new SudokuMCVE();
JFrame frame = new JFrame("SudokuMCVE");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
Which displays as:
其中显示为:
Or with JButtons:
或者使用 JButtons:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
@SuppressWarnings("serial")
public class JPanelGrid extends JPanel {
private static final int SML_SIDE = 3;
private static final int SIDE = SML_SIDE * SML_SIDE;
private static final int GAP = 3;
private static final Color BG = Color.BLACK;
private static final Dimension BTN_PREF_SIZE = new Dimension(80, 80);
private JButton[][] buttons = new JButton[SIDE][SIDE];
public JPanelGrid() {
setBackground(BG);
setLayout(new GridLayout(SML_SIDE, SML_SIDE, GAP, GAP));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
JPanel[][] smallPanels = new JPanel[SML_SIDE][SML_SIDE];
for (int i = 0; i < smallPanels.length; i++) {
for (int j = 0; j < smallPanels[i].length; j++) {
smallPanels[i][j] = new JPanel(new GridLayout(SML_SIDE, SML_SIDE));
add(smallPanels[i][j]);
}
}
for (int i = 0; i < buttons.length; i++) {
int panelI = i / SML_SIDE;
for (int j = 0; j < buttons[i].length; j++) {
int panelJ = j / SML_SIDE;
String text = String.format("[%d, %d]", j, i);
buttons[i][j] = new JButton(text);
buttons[i][j].setPreferredSize(BTN_PREF_SIZE);
smallPanels[panelI][panelJ].add(buttons[i][j]);
}
}
}
private static void createAndShowGui() {
JPanelGrid mainPanel = new JPanelGrid();
JFrame frame = new JFrame("JPanelGrid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
Which displays:
其中显示:
回答by guleryuz
I made these minimal modifications in your code,
- add buttons to panel (not to frame)
- set panel as frame's content pane
- change method paint
with paintComponent
and call firstly super.paintComponent
in method body
- and change line coordinate calculations
我做了你的代码,这些最小的修改,
-按钮添加到面板(不帧)
-设置面板框架的内容窗格
-变化的方法paint
有paintComponent
,首次调用super.paintComponent
在方法体
-和改变线路坐标计算
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ButtonGrid extends JPanel {
JFrame frame = new JFrame();
int t = 9;
public ButtonGrid() { // constructor
frame.setContentPane(this);
setLayout(new GridLayout(t, t, 3, 3));
addButtons(t);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// g.setColor(getBackground());
// g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.RED);
for (int i = 0; i <= 9; i++) {
if (i % 3 == 0) {
int coordx = getWidth() * i / 9;
int coordy = getHeight() * i / 9;
g.drawLine(coordx, 0, coordx, getHeight());
g.drawLine(0, coordy, getWidth(), coordy);
}
}
}
private void addButtons(int t) {
JButton grid;
for (int y = 0; y < t; y++) {
for (int x = 0; x < t; x++) {
grid = new JButton(x + "," + y); // creates new button
grid.setPreferredSize(new Dimension(55, 55));
add(grid); // adds button to grid
}
}
}
public static void main(String[] args) {
new ButtonGrid();
}
}