JAVA进阶技术之四:Java 图形图像-编程与艺术的结合
小标题:探秘 Java 图形图像:代码编织的视觉艺术绮梦
在现代生活中,桌面应用程序依旧不可或缺。尽管移动应用盛行,但桌面程序在处理复杂任务时优势显著。如专业图形设计,桌面软件凭借强大功能与高运算能力,能精准实现创意。办公领域,功能全面的文档处理桌面应用保障高效工作。 不难看出,时至今日桌面应用在各个领域稳固扎根,持续发挥重要作用。
一、前言
在 Java 开发领域,图形图像编程占据着重要地位,它能够为用户打造出直观、交互性强的界面体验。Java Swing 作为构建图形用户界面(GUI)的强大工具包,具有卓越的跨平台特性,这意味着开发者只需编写一次代码,就能在不同操作系统上运行,为广泛的用户群体提供一致的服务。相较于早期的 AWT(Abstract Window Toolkit),Swing 提供了更加丰富的组件库和灵活的外观定制功能,不过在性能方面,由于其高度的抽象性,在某些极端场景下可能稍逊一筹。而 Graphics 类则宛如一位幕后的绘画大师,掌控着图形绘制的每一个细节,无论是简单的线条勾勒,还是复杂的图像渲染,都离不开它的支持。接下来,让我们深入探究它们的奥秘。
二、Swing 基础组件概览
Swing 为开发者提供了琳琅满目的基础组件,犹如搭建大厦的基石。以 JFrame 为例,它作为顶级容器,是整个 GUI 的承载框架,定义了窗口的基本属性,如大小、位置、标题等。创建一个简单的 JFrame 窗口代码如下: import javax.swing.JFrame;
public class SimpleFrame { public static void main(String[] args) { JFrame frame = new JFrame("My First Frame"); frame.setSize(400, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
JButton 则是交互的关键推动者,用户点击按钮触发相应的事件,为程序注入活力。JLabel 常用于显示文本信息或图标,起到提示、说明的作用,帮助用户更好地理解界面功能。这些组件相互协作,初步构建起了一个功能完备的用户界面雏形。
三、布局管理器的奥秘
布局管理器是 Swing 界面井然有序的 “指挥官”。FlowLayout 采用流式布局,组件按照添加的顺序依次排列,若一行空间不足,则自动换行,适用于简单的、对布局规整性要求不高的场景,如工具条的布局。代码示例:
import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.FlowLayout;
public class FlowLayoutExample { public static void main(String[] args) { JFrame frame = new JFrame("FlowLayout Example"); JPanel panel = new JPanel(new FlowLayout()); JButton button1 = new JButton("Button 1"); JButton button2 = new JButton("Button 2"); JButton button3 = new JButton("Button 3"); panel.add(button1); panel.add(button2); panel.add(button3); frame.add(panel); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
BorderLayout 将容器划分为东、南、西、北、中五个区域,开发者可根据需求将组件精准放置到特定区域,常用于主窗口的布局划分。GridLayout 把容器空间等分成若干网格,组件按照行列顺序依次填充,在表格形式布局需求中表现出色。不同的布局管理器各具特色,为开发者应对多样化的界面设计需求提供了有力保障。
四、Swing 应用案例展示
(一)简单计算器应用案例
利用 BorderLayout 和 GridLayout 能巧妙构建简单计算器界面。核心代码如下:
import javax.swing.; import java.awt.; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;
public class Calculator { public static void main(String[] args) { JFrame frame = new JFrame("Calculator"); frame.setSize(300, 400); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JTextField textField = new JTextField();
panel.add(textField, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(4, 4));
String[] buttonLabels = {
"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "-",
"0", ".", "=", "+"
};
for (String label : buttonLabels) {
JButton button = new JButton(label);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("=")) {
try {
double result = evaluateExpression(textField.getText());
textField.setText(String.valueOf(result));
} catch (Exception ex) {
textField.setText("Error");
}
} else {
textField.setText(textField.getText() + command);
}
}
});
buttonPanel.add(button);
}
panel.add(buttonPanel, BorderLayout.CENTER);
frame.add(panel);
frame.setVisible(true);
}
private static double evaluateExpression(String expression) {
// 这里可以实现具体的表达式求值逻辑,为简化示例,暂未详细展开
return 0;
}
}
通过上述代码,实现了计算器的基本界面搭建以及按钮点击的交互逻辑,用户输入数字和运算符,点击 “=” 按钮后能得到简单的计算结果。
(二)个人信息填写表单应用案例
使用 BorderLayout、GridBagLayout 搭建个人信息填写表单,代码如下:
import javax.swing.; import java.awt.;
public class PersonalInfoForm { public static void main(String[] args) { JFrame frame = new JFrame("Personal Information Form"); frame.setSize(500, 400); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JPanel formPanel = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
JLabel nameLabel = new JLabel("Name:");
JTextField nameTextField = new JTextField(20);
constraints.gridx = 0;
constraints.gridy = 0;
formPanel.add(nameLabel, constraints);
constraints.gridx = 1;
constraints.gridy = 0;
formPanel.add(nameTextField, constraints);
JLabel ageLabel = new JLabel("Age:");
JTextField ageTextField = new JTextField(5);
constraints.gridx = 0;
constraints.gridy = 1;
formPanel.add(ageLabel, constraints);
constraints.gridx = 1;
constraints.gridy = 1;
formPanel.add(ageTextField, constraints);
JLabel genderLabel = new JLabel("Gender:");
JRadioButton maleButton = new JRadioButton("Male");
JRadioButton femaleButton = new JRadioButton("Female");
ButtonGroup genderGroup = new ButtonGroup();
genderGroup.add(maleButton);
genderGroup.add(femaleButton);
constraints.gridx = 0;
constraints.gridy = 2;
formPanel.add(genderLabel, constraints);
constraints.gridx = 1;
constraints.gridy = 2;
formPanel.add(maleButton, constraints);
constraints.gridx = 2;
constraints.gridy = 2;
formPanel.add(femaleButton, constraints);
JLabel hobbiesLabel = new JLabel("Hobbies:");
JCheckBox readingCheckBox = new JCheckBox("Reading");
JCheckBox sportsCheckBox = new JCheckBox("Sports");
JCheckBox musicCheckBox = new JCheckBox("Music");
constraints.gridx = 0;
constraints.gridy = 3;
formPanel.add(hobbiesLabel, constraints);
constraints.gridx = 1;
constraints.gridy = 3;
formPanel.add(readingCheckBox, constraints);
constraints.gridx = 2;
constraints.gridy = 3;
formPanel.add(sportsCheckBox, constraints);
constraints.gridx = 3;
constraints.gridy = 3;
formPanel.add(musicCheckBox, constraints);
JButton submitButton = new JButton("Submit");
constraints.gridx = 0;
constraints.gridy = 4;
formPanel.add(submitButton, constraints);
panel.add(formPanel, BorderLayout.CENTER);
frame.add(panel);
frame.setVisible(true);
}
}
在此案例中,实现了包含文本框、单选框、复选框等多种组件的个人信息表单,用户可以填写个人资料,点击 “Submit” 按钮后可进行后续的数据处理(此处未详细展开提交后的处理逻辑)。
(三)对话框应用案例
创建对话框的代码示例:
import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener;
public class DialogExample { public static void main(String[] args) { JFrame frame = new JFrame("Dialog Example"); frame.setSize(300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Open Dialog");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JDialog dialog = new JDialog(frame, "My Dialog", true);
dialog.setSize(200, 150);
JPanel panel = new JPanel();
JLabel label = new JLabel("This is a dialog.");
panel.add(label);
dialog.add(panel);
dialog.setVisible(true);
}
});
frame.add(button);
frame.setVisible(true);
}
}
这段代码展示了在主窗体中触发弹出对话框的过程,对话框包含简单的文本提示信息,通过设置对话框的属性,如标题、大小、阻塞属性(此处设置为 true,意味着对话框弹出时主窗口操作将被阻塞,直到对话框关闭),满足了一些特定的交互需求。
五、Graphics 全知晓:图形绘制的得力助手
Graphics 类是 Java 图形绘制的核心工具,它是所有图形上下文的抽象基类。在组件绘制场景下,当需要自定义组件的外观,如绘制特殊形状的按钮、装饰性的面板时,Graphics 就派上用场了。例如,要在一个 JPanel 上绘制一个红色的圆形,代码如下:
import javax.swing.; import java.awt.;
public class GraphicsExample extends JPanel { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.RED); g.fillOval(50, 50, 100, 100); }
public static void main(String[] args) {
JFrame frame = new JFrame("Graphics Example");
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GraphicsExample panel = new GraphicsExample();
frame.add(panel);
frame.setVisible(true);
}
}
在上述代码中,重写了 JPanel 的 paintComponent 方法,通过 Graphics 对象获取图形上下文,设置颜色为红色后,使用 fillOval 方法绘制了一个左上角坐标为 (50, 50),宽高为 100 的圆形。它在闭屏图像绘制方面同样表现出色,比如在后台生成图像缓存,提高图形显示的效率和流畅性,避免闪烁等问题。
六、Swing 与 Graphics 的紧密关联
Swing 起步于 AWT 的基本绘画模式,在此基础上进行了大幅度的扩展,从而获得了更好的性能与更多的功能。在 Swing 组件中使用 Graphics 画图时,涉及到一些特殊的属性和机制。双缓冲技术就是其中之一,它通过在内存中创建一个与屏幕显示区域相同的缓冲区,先在缓冲区中进行图形绘制操作,待绘制完成后,一次性将缓冲区的内容复制到屏幕上,有效避免了图形绘制过程中的闪烁现象。例如:
import javax.swing.; import java.awt.; import java.awt.image.BufferedImage;
public class SwingGraphicsBuffer extends JPanel { private BufferedImage buffer;
public SwingGraphicsBuffer() {
setPreferredSize(new Dimension(400, 400));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (buffer == null) {
buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
}
Graphics2D g2d = buffer.createGraphics();
g2d.setColor(Color.BLUE);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.YELLOW);
g2d.drawString("Hello, Graphics in Swing!", 100, 200);
g.drawImage(buffer, 0, 0, this);
g2d.dispose();
}
public static void main(String[] args) {
JFrame frame = new JFrame("Swing Graphics with Buffer");
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SwingGraphicsBuffer panel = new SwingGraphicsBuffer();
frame.add(panel);
frame.setVisible(true);
}
}
在这个示例中,首先创建了一个 BufferedImage 作为缓冲区,在缓冲区的 Graphics2D 对象上进行绘制蓝色矩形和黄色文字的操作,最后将缓冲区图像绘制到屏幕上,实现了流畅的图形显示效果。遮光属性则可以控制图形之间的遮挡关系,通过合理设置,能够营造出更加立体、层次感丰富的视觉效果。
七、Applet、Swing、Graphics 三者之间的联系和区别
Applet 是一种可嵌入 HTML 页面中运行的 Java 小程序,它曾经在网络应用早期大放异彩,为网页带来了动态交互的能力。与 Swing 相比,Applet 基于的底层库在某些方面存在差异,Applet 更多地依赖于浏览器环境提供的支持,而 Swing 具有更强的独立性,能够构建独立的桌面应用程序。在样式呈现上,Applet 受浏览器兼容性影响较大,样式定制相对受限,Swing 则可以通过 Look and Feel 机制灵活地改变外观样式,满足不同用户的审美需求。
Graphics 与 Applet、Swing 的关联主要体现在图形绘制层面。在 Applet 中,同样可以使用 Graphics 类来绘制图形,实现简单的动画效果或者可视化展示,只不过其绘制的区域通常是在嵌入的 HTML 页面所分配的空间内。而在 Swing 中,如前文所述,Graphics 用于定制组件外观、绘制复杂图形等,为构建精美、交互性强的 GUI 提供支持。从应用场景侧重来看,Applet 侧重于在网络环境下为网页增添动态元素,Swing 专注于打造功能完备的桌面应用图形界面,Graphics 则作为二者实现图形绘制功能的关键工具,发挥着不可或缺的作用,但其本身并不具备构建完整应用的能力,需要依托于 Applet 或 Swing 等框架来施展拳脚。
八、总结
回顾全文,我们深入了解了 Java Swing 的基础组件、布局管理器以及丰富多彩的应用案例,感受到了它在构建强大桌面应用方面的魅力。同时,认识了 Graphics 类在图形绘制领域的核心地位和卓越能力,以及它与 Swing 之间紧密的协作关系。此外,还厘清了 Applet、Swing、Graphics 三者之间的联系与区别。在实际开发中,开发者应根据具体的需求,巧妙运用这些技术,充分发挥它们的优势,打造出既美观又实用的 Java 应用程序,为用户带来优质的体验。无论是开发简单的工具软件,还是复杂的企业级应用,掌握这些知识都将为我们的编程之路点亮明灯。
最近一直在研究AI公众号爆文的运维逻辑,也在学习各种前沿的AI技术,加入了不会笑青年和纯洁的微笑两位大佬组织起来的知识星球,也开通了自己的星球:
怡格网友圈,地址是:https://wx.zsxq.com/group/51111855584224
这是一个付费的星球,暂时我还没想好里面放什么,现阶段不建议大家付费和进入我自己的星球,即使有不小心付费的,我也会直接退费,无功不受禄。如果你也对AI特别感兴趣,推荐你付费加入他们的星球:
AI俱乐部,地址是:https://t.zsxq.com/mRfPc 。
建议大家先加 微信号:yeegee2024 或者关注微信公众号:yeegeexb2014 咱们产品成型了之后,咱们再一起进入星球,一起探索更美好的未来!