我有一个100 x 100的标签网格。我有一个创建和填充字符串数组的方法。下一个方法创建一个标签数组,然后使用setText()方法将String(从先前方法创建)添加到标签。一些标签也包含图像。之后的方法采用那些JLabel并将它们添加到网格布局的JPanel(让我们调用这个x1)。然后我将JPanel添加到JScrollPane(x2),JScrollPane被添加到另一个带有空边框的JPanel(x3),最后的JPanel(x3)被添加到JFrame。这就是我创建网格的方式,我很满意,我不想改变它。
我想将图像添加到x1 - 带有网格布局的JPanel。 为此,我必须添加paintComponent方法并使用drawImage()方法。我的问题是Eclipse将如何知道将图像添加到哪个面板?我不想为x1创建一个单独的课程,我之前就是这样做的,它只是没有正常工作,我宁愿再次走下那条令人难以置信的令人沮丧的道路,我很抱歉!< / p>
我考虑过使用Glass Pane但是我不再能够看到JLabels的图像 - 这非常重要。
我认为将图像添加到JPanel的背景将是最好的,因为我还想要一个显示/隐藏网格线的按钮 - JLabel的边框。
我希望我有道理。
以下是代码。我理解它在一个类中有很多代码。我确实在两个单独的课程中有它,但它只是没有工作我。我发现这更容易了。我希望你不要介意
package roverMars;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
public class MenuPanel extends JPanel {
private static final long serialVersionUID = -3928152660110599311L;
public JPanel frame, textfield, buttons, cpPanel;
public JTextField Commands;
public JButton Plot, Submit, Undo;
public JLabel Position, cpLabel;
public Border loweredetched;
public JCheckBox gridLines;
public SubmitButton sub;
static final int rows = 100, columns = 100;
// ******IMAGES******
static BufferedImage North, South, West, East;
public void ImageLoader() {
try {
North = ImageIO.read(this.getClass().getResource("North.png"));
South = ImageIO.read(this.getClass().getResource("South.png"));
West = ImageIO.read(this.getClass().getResource("West.png"));
East = ImageIO.read(this.getClass().getResource("East.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Error occured: " + e);
e.printStackTrace();
}
}
// ******IMAGES******
public void createMenu(JPanel p) {
// Text Field Panel
Commands = new JTextField(20);
textfield = new JPanel();
textfield.setPreferredSize(new Dimension(150, 50));
textfield.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
textfield.setBackground(new Color(204, 153, 255));
textfield.add(Commands);
// Have a button next to the Text Field to clear contents.
// Might need to give the JPanel a new Flow Layout.
// Buttons Panel
buttons = new JPanel();
buttons.setPreferredSize(new Dimension(150, 250));
buttons.setLayout(new BoxLayout(buttons, BoxLayout.Y_AXIS));
buttons.setBackground(new Color(170, 051, 170));
// Create and Add buttons to the Buttons Panel
buttons.add(Box.createRigidArea(new Dimension(30, 10)));
Plot = new JButton("Plot");
Plot.setAlignmentX(Component.CENTER_ALIGNMENT);
Plot.setAlignmentY(Component.CENTER_ALIGNMENT);
buttons.add(Plot);
buttons.add(Box.createRigidArea(new Dimension(30, 10)));
Submit = new JButton("Submit");
Submit.setAlignmentX(Component.CENTER_ALIGNMENT);
Submit.setAlignmentY(Component.CENTER_ALIGNMENT);
Submit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sub = new SubmitButton();
sub.Submit(Commands);
cpLabel.setText("*****SET CURRENT POSITION*****");
labels[2][2].setIcon(new ImageIcon(North));
// I will be able to move the rover from here using for loops
// and if statements.
}
});
buttons.add(Submit);
buttons.add(Box.createRigidArea(new Dimension(30, 10)));
Undo = new JButton("Undo");
Undo.setAlignmentX(Component.CENTER_ALIGNMENT);
Undo.setAlignmentY(Component.CENTER_ALIGNMENT);
buttons.add(Undo);
buttons.add(Box.createRigidArea(new Dimension(30, 10)));
gridLines = new JCheckBox();
gridLines.setText("Show gridlines");
gridLines.setAlignmentX(Component.CENTER_ALIGNMENT);
gridLines.setAlignmentY(Component.CENTER_ALIGNMENT);
gridLines.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// Set the colour of the JLabels array from here.
System.out.println("clicked");
}
});
buttons.add(gridLines);
buttons.add(Box.createRigidArea(new Dimension(30, 20)));
loweredetched = BorderFactory
.createEtchedBorder(EtchedBorder.RAISED);
cpLabel = new JLabel("Current position: ", JLabel.CENTER);
cpPanel = new JPanel();
cpPanel.setBackground(new Color(153, 153, 204));
cpPanel.add(cpLabel);
cpPanel.setBorder(loweredetched);
// Panel for the main window
JPanel frame = new JPanel();
frame.setPreferredSize(new Dimension(150, 350));
frame.setLayout(new BorderLayout());
frame.add(textfield, BorderLayout.NORTH);
frame.add(buttons, BorderLayout.CENTER);
// This Main Panel
p.setPreferredSize(new Dimension(350, 700));
p.setBackground(new Color(153, 153, 204));
p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
p.setBorder(BorderFactory.createEmptyBorder(10, 50, 10, 25));
p.add(Box.createRigidArea(new Dimension(100, 100)));
p.add(frame);
p.add(Box.createRigidArea(new Dimension(15, 15)));
p.add(cpPanel);
p.add(Box.createRigidArea(new Dimension(100, 300)));
}
// From line 142 to 202 is everything to do with creating the Grid
public void StringArray(String[][] labelText) {
int x = 1; // increment rows
for (int i = 0; i < labelText.length; i++) { // x
for (int j = 0; j < labelText.length; j++) { // y
labelText[i][j] = Integer.toString(x); // populate string
x++;
}
}
}
public void JLabelArray(JLabel[][] label, String[][] labelText) {
for (int i = 0; i < label.length; i++) { // x
for (int j = 0; j < label.length; j++) { // y
label[i][j] = new JLabel();
label[i][j].setText(labelText[i][j]);
label[i][j].setOpaque(false);
label[i][j].setBorder(BorderFactory.createLineBorder(new Color(
0, 155, 200), 1));
// label[i][j].setBackground(Color.WHITE);
}
}
}
public void populateGrid(JPanel Grid, JLabel[][] label) { // Add Labels to
// Panel,
String x1[][] = new String[rows][columns];
StringArray(x1);
JLabelArray(label, x1);
Grid.setBackground(Color.RED);
int gHeight = label.length, gWidth = label.length;
Grid.setLayout(new GridLayout(gWidth, gHeight));
for (int i = 0; i < label.length; i++) { // x
for (int j = 0; j < label.length; j++) { // y
Grid.add(label[i][j]);
}
}
}
public void createGrid(JPanel finalPanel, JPanel Grid) {
// Add Grid to Scroll Pane
JScrollPane x4 = new JScrollPane(Grid);
x4.setPreferredSize(new Dimension(600, 600)); // DO NOT DELETE THIS.
x4.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
x4.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
// Add Scroll Pane to another Panel with the Border
finalPanel.setBackground(new Color(153, 153, 204));
finalPanel.setBorder(BorderFactory.createEmptyBorder(50, 25, 50, 50));
finalPanel.add(x4);
}
// Variables for creaeteGUI method.
static MenuPanel t = new MenuPanel();
static JPanel menu = new JPanel();
static JPanel finalPanel = new JPanel();
static JPanel gridPanel = new JPanel();
static JLabel labels[][] = new JLabel[rows][columns];
public static void createGUI() {
t.createMenu(menu);
t.populateGrid(gridPanel, labels);
t.createGrid(finalPanel, gridPanel);
JFrame f = new JFrame();
f.setTitle("Project Testing");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setLocation(100, 100);
f.setAlwaysOnTop(true);
f.setSize(500, 500);
f.add(finalPanel, BorderLayout.CENTER);
f.add(menu, BorderLayout.WEST);
f.pack();
}
public static void main(String args[]) {
createGUI();
t.ImageLoader();
labels[2][2].setIcon(new ImageIcon(West));
}
}
非常感谢你!我非常感谢任何帮助或建议:D
答案 0 :(得分:1)
正如您所说,您需要做的是覆盖JPanel的paintComponent
方法并在其中放置drawImage(...)
。所以:
@Override
public void paintComponent(Graphics g)
{
//super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
其中image
是您之前在初始化代码中加载的类Image
的实例(不要将它加载到paintComponent中,这样会太慢而您只想要加载一次)。
有两种方法可以实现这一目标:
让您自己的类扩展JPanel
并将该代码放在那里。您可能还想创建一个方法setBackgroundImage(Image)
,您可以从主类调用该方法来传递从磁盘加载的图像。
创建一个anonymous class,即做类似但没有明确定义新类的东西。要这样做而不是像这样创建面板:
JPanel gridPanel = new JPanel();
这样做:
JPanel gridPanel = new JPanel()
{
@Override
public void paintComponent(Graphics g)
{
//super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
};
当然,您必须在实际代码中执行此操作(而不是作为静态初始化),因为您要确保以前加载图像。
最后提出几点建议:
变量名按惯例以小写字母开头(与以大写字母开头的类名相反)。例如,您不必在JPanel Grid
参数和Comands
字段中执行此操作。
您违反了Swing的单线程规则。也就是说,您必须在主要包装GUI初始化代码中调用invokeLater
。例如,看看Swing的Hello World。您可以找到此here。