JLabel - 切断图像的顶部
JLabel - Cutting Off The Top of Image
在我的新 Java 项目中,我有一个 JFrame,其中有一个 JLabel 设置为带有 BorderLayout 的 North,它下面是一个图像。该图像在 JFrame 上很合适,但 JLabel 切掉了它的顶部。我如何调整这个 JLabel 的大小?我试过 setPreferredSize
但没用。帮助将不胜感激。
代码:
package counter.main;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class FoodCounter {
public static JLabel greet4 = new JLabel("",SwingConstants.CENTER);
public static JLabel message4 = new JLabel();
public static JLabel lclicks4 = new JLabel();
public static JButton buttonClick4 = new JButton("+ Food");
public static int clicks4 = 0;
public static URL food = Main.class.getResource("/counter/main/FoodEating.wav");
public static JButton back = new JButton("Back");
public static JLabel bread;
static JFrame frame = new JFrame("Food Counter"); {
createView();
frame.setSize(500, 100);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.revalidate();
frame.repaint();
}
private void createView() {
final JPanel panelc = new JPanel();
frame.getContentPane().add(panelc);
panelc.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 11));
greet4.setFont(new Font( "Dialog", Font.PLAIN, 18));
greet4.setPreferredSize(new Dimension(40, 20));
panelc.add(message4);
frame.add(back, BorderLayout.WEST);
frame.add(greet4, BorderLayout.NORTH);
back.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.setVisible(false);
SelectionFrame.frame1.setVisible(true);
}
});
panelc.add(buttonClick4);
panelc.add(lclicks4);
updateCounter();
bread = new JLabel("");
bread.setPreferredSize(new Dimension(64, 64));
Image img = new ImageIcon(this.getClass().getResource("/counter/main/SlicedBread64.png")).getImage();
bread.setIcon(new ImageIcon(img));
frame.getContentPane().add(bread, BorderLayout.EAST);
buttonClick4.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
clicks4++;
updateCounter();
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(food);
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch (IOException | UnsupportedAudioFileException | LineUnavailableException x) {
x.printStackTrace();
}
}
});
};
private void updateCounter() {
lclicks4.setText(clicks4 + "/100 Food ");
if (clicks4 < 1) {
message4.setText("Click to Begin! -->");
}
if (clicks4 >= 1 && clicks4 < 10) {
message4.setText("Keep Going!");
}
if (clicks4 >= 10 && clicks4 < 50) {
message4.setText("Keep 'em Comin'!");
}
if (clicks4 >= 50 && clicks4 < 70) {
message4.setText("Don't Stop!");
}
if (clicks4 >= 70 && clicks4 < 80) {
message4.setText("Almost!");
}
if (clicks4 >= 90 && clicks4 < 100) {
message4.setText("Finish Strong!");
}
if (clicks4 >= 100) {
try {
Thread.sleep(3000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
System.exit(0);
}
}
}
- 不要在组件上设置大小、首选大小或类似问题,top-level windows 如果可以避免的话。
- 相反,通过巧妙地使用布局管理器并在添加所有组件之后调用
setVisible(true)
之前在 top-level window 上调用 pack()
,让 GUI 自行调整大小。
- 考虑将虚拟文本放入 greet4 JLabel,以便在打包 GUI 时占用 space。一些 space,
" "
可能就足够了。
不相关的推荐:
- 你的大部分变量应该是 instance 变量,而不是 static 变量。 Java 是根据 object-oriented 编程原则构建的,原因有很多,但主要的原因是减少连接及其相关的复杂性。通过使用静态变量和方法,您可以消除这种好处并冒着创建具有高度圈复杂度的程序的风险,从而使调试变得困难。
- 声明为
public
的变量也是如此。更喜欢使用 private
字段来帮助减少耦合并增加内聚性。
- 运行 long-running 代码(例如播放音乐的代码)在后台线程中以避免占用 Swing 事件线程。
- 切勿在 Swing 事件调度线程或 EDT 中调用
Thread.sleep(...)
,因为这会使整个 Swing GUI 进入休眠状态。
例如,
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class FoodCounter2 extends JPanel {
public static final String IMAGE_PATH = "https://duke.kenai.com/iconSized/duke.gif";
private static final Font TITLE_FONT = new Font("Dialog", Font.PLAIN, 18);
private JLabel titleLabel = new JLabel("Welcome, User", SwingConstants.CENTER);
private JButton backButton = new JButton("Back");
private JButton addFoodButton = new JButton("+ Food");
private JLabel foodCountLabel = new JLabel("0/100 Food");
public FoodCounter2() throws IOException {
URL imgUrl = new URL(IMAGE_PATH);
BufferedImage img = ImageIO.read(imgUrl);
ImageIcon icon = new ImageIcon(img);
JPanel foodPanel = new JPanel(new GridBagLayout());
// JPanel foodPanel = new JPanel();
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10, 10, 10, 10);
foodPanel.add(new JLabel("Click to Begin! --->"), gbc);
gbc.gridx++;
foodPanel.add(addFoodButton, gbc);
gbc.gridx++;
foodPanel.add(foodCountLabel, gbc);
JPanel centerPanel = new JPanel(new BorderLayout());
titleLabel.setFont(TITLE_FONT);
centerPanel.add(titleLabel, BorderLayout.PAGE_START);
centerPanel.add(foodPanel, BorderLayout.CENTER);
setLayout(new BorderLayout());
add(backButton, BorderLayout.LINE_START);
add(centerPanel, BorderLayout.CENTER);
add(new JLabel(icon), BorderLayout.LINE_END);
}
private static void createAndShowGui() {
FoodCounter2 mainPanel = null;
try {
mainPanel = new FoodCounter2();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("FoodCounter2");
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(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
显示为:
这是正在发生的事情:
如您所见,面包的顶部被切掉了。我认为这是因为 JPanel 正在覆盖它。
在我的新 Java 项目中,我有一个 JFrame,其中有一个 JLabel 设置为带有 BorderLayout 的 North,它下面是一个图像。该图像在 JFrame 上很合适,但 JLabel 切掉了它的顶部。我如何调整这个 JLabel 的大小?我试过 setPreferredSize
但没用。帮助将不胜感激。
代码:
package counter.main;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
public class FoodCounter {
public static JLabel greet4 = new JLabel("",SwingConstants.CENTER);
public static JLabel message4 = new JLabel();
public static JLabel lclicks4 = new JLabel();
public static JButton buttonClick4 = new JButton("+ Food");
public static int clicks4 = 0;
public static URL food = Main.class.getResource("/counter/main/FoodEating.wav");
public static JButton back = new JButton("Back");
public static JLabel bread;
static JFrame frame = new JFrame("Food Counter"); {
createView();
frame.setSize(500, 100);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.revalidate();
frame.repaint();
}
private void createView() {
final JPanel panelc = new JPanel();
frame.getContentPane().add(panelc);
panelc.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 11));
greet4.setFont(new Font( "Dialog", Font.PLAIN, 18));
greet4.setPreferredSize(new Dimension(40, 20));
panelc.add(message4);
frame.add(back, BorderLayout.WEST);
frame.add(greet4, BorderLayout.NORTH);
back.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.setVisible(false);
SelectionFrame.frame1.setVisible(true);
}
});
panelc.add(buttonClick4);
panelc.add(lclicks4);
updateCounter();
bread = new JLabel("");
bread.setPreferredSize(new Dimension(64, 64));
Image img = new ImageIcon(this.getClass().getResource("/counter/main/SlicedBread64.png")).getImage();
bread.setIcon(new ImageIcon(img));
frame.getContentPane().add(bread, BorderLayout.EAST);
buttonClick4.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
clicks4++;
updateCounter();
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(food);
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch (IOException | UnsupportedAudioFileException | LineUnavailableException x) {
x.printStackTrace();
}
}
});
};
private void updateCounter() {
lclicks4.setText(clicks4 + "/100 Food ");
if (clicks4 < 1) {
message4.setText("Click to Begin! -->");
}
if (clicks4 >= 1 && clicks4 < 10) {
message4.setText("Keep Going!");
}
if (clicks4 >= 10 && clicks4 < 50) {
message4.setText("Keep 'em Comin'!");
}
if (clicks4 >= 50 && clicks4 < 70) {
message4.setText("Don't Stop!");
}
if (clicks4 >= 70 && clicks4 < 80) {
message4.setText("Almost!");
}
if (clicks4 >= 90 && clicks4 < 100) {
message4.setText("Finish Strong!");
}
if (clicks4 >= 100) {
try {
Thread.sleep(3000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
System.exit(0);
}
}
}
- 不要在组件上设置大小、首选大小或类似问题,top-level windows 如果可以避免的话。
- 相反,通过巧妙地使用布局管理器并在添加所有组件之后调用
setVisible(true)
之前在 top-level window 上调用pack()
,让 GUI 自行调整大小。 - 考虑将虚拟文本放入 greet4 JLabel,以便在打包 GUI 时占用 space。一些 space,
" "
可能就足够了。
不相关的推荐:
- 你的大部分变量应该是 instance 变量,而不是 static 变量。 Java 是根据 object-oriented 编程原则构建的,原因有很多,但主要的原因是减少连接及其相关的复杂性。通过使用静态变量和方法,您可以消除这种好处并冒着创建具有高度圈复杂度的程序的风险,从而使调试变得困难。
- 声明为
public
的变量也是如此。更喜欢使用private
字段来帮助减少耦合并增加内聚性。 - 运行 long-running 代码(例如播放音乐的代码)在后台线程中以避免占用 Swing 事件线程。
- 切勿在 Swing 事件调度线程或 EDT 中调用
Thread.sleep(...)
,因为这会使整个 Swing GUI 进入休眠状态。
例如,
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class FoodCounter2 extends JPanel {
public static final String IMAGE_PATH = "https://duke.kenai.com/iconSized/duke.gif";
private static final Font TITLE_FONT = new Font("Dialog", Font.PLAIN, 18);
private JLabel titleLabel = new JLabel("Welcome, User", SwingConstants.CENTER);
private JButton backButton = new JButton("Back");
private JButton addFoodButton = new JButton("+ Food");
private JLabel foodCountLabel = new JLabel("0/100 Food");
public FoodCounter2() throws IOException {
URL imgUrl = new URL(IMAGE_PATH);
BufferedImage img = ImageIO.read(imgUrl);
ImageIcon icon = new ImageIcon(img);
JPanel foodPanel = new JPanel(new GridBagLayout());
// JPanel foodPanel = new JPanel();
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10, 10, 10, 10);
foodPanel.add(new JLabel("Click to Begin! --->"), gbc);
gbc.gridx++;
foodPanel.add(addFoodButton, gbc);
gbc.gridx++;
foodPanel.add(foodCountLabel, gbc);
JPanel centerPanel = new JPanel(new BorderLayout());
titleLabel.setFont(TITLE_FONT);
centerPanel.add(titleLabel, BorderLayout.PAGE_START);
centerPanel.add(foodPanel, BorderLayout.CENTER);
setLayout(new BorderLayout());
add(backButton, BorderLayout.LINE_START);
add(centerPanel, BorderLayout.CENTER);
add(new JLabel(icon), BorderLayout.LINE_END);
}
private static void createAndShowGui() {
FoodCounter2 mainPanel = null;
try {
mainPanel = new FoodCounter2();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
JFrame frame = new JFrame("FoodCounter2");
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(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
显示为:
这是正在发生的事情:
如您所见,面包的顶部被切掉了。我认为这是因为 JPanel 正在覆盖它。