我: 用Java开发一款桌面便签软件。功能需求:1、便签可以钉在桌面任意角落;2、便签内容实时保存到本地;3、有新增按钮,点击新增时清除当前面板上的内容,新建一条新的便签内容,并保存到本地;4、有查看便签历史功能,点击查看历史,可以查看之前新建的每一条便签内容(因为便签内容保存到本地了,所以是可以查看历史内容的);根据以上4点要求,请帮我写出完整代码。
chatgpt: 以下是一个简单的Java代码示例,实现了您所描述的便签软件的功能需求:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.List;public class DesktopNoteApp extends JFrame {private List<String> notes;private JTextArea noteTextArea;public DesktopNoteApp() {notes = new ArrayList<>();loadNotes();setTitle("桌面便签");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setResizable(false);setLayout(new BorderLayout());noteTextArea = new JTextArea();noteTextArea.setLineWrap(true);noteTextArea.setFont(new Font("Arial", Font.PLAIN, 14));JScrollPane scrollPane = new JScrollPane(noteTextArea);scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);add(scrollPane, BorderLayout.CENTER);JPanel buttonPanel = new JPanel();buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));JButton newButton = new JButton("新增");newButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String note = noteTextArea.getText();notes.add(note);saveNotes();noteTextArea.setText("");}});buttonPanel.add(newButton);JButton historyButton = new JButton("查看历史");historyButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {StringBuilder history = new StringBuilder();for (String note : notes) {history.append(note).append("\n");}JOptionPane.showMessageDialog(null, history.toString(), "便签历史", JOptionPane.INFORMATION_MESSAGE);}});buttonPanel.add(historyButton);add(buttonPanel, BorderLayout.SOUTH);pack();setLocationRelativeTo(null);setVisible(true);}private void loadNotes() {try {File file = new File("notes.txt");if (file.exists()) {BufferedReader reader = new BufferedReader(new FileReader(file));String line;while ((line = reader.readLine()) != null) {notes.add(line);}reader.close();}} catch (IOException e) {e.printStackTrace();}}private void saveNotes() {try {BufferedWriter writer = new BufferedWriter(new FileWriter("notes.txt"));for (String note : notes) {writer.write(note);writer.newLine();}writer.close();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {@Overridepublic void run() {new DesktopNoteApp();}});}
}
请注意,此代码仅为示例,可能需要根据您的具体需求进行修改和完善。
运行效果
窗口太小、不是置于顶层、无法拖动。新增和查看历史倒是实现了。
我: 窗口需要可以拖动,并且置于顶层,还有窗口大小调整为400*500
chatgpt: 以下是修改后的代码,实现了窗口可以拖动、置于顶层以及窗口大小调整为400*500的功能:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.ArrayList;
import java.util.List;public class DesktopNoteApp extends JFrame {private List<String> notes;private JTextArea noteTextArea;private Point initialClick;public DesktopNoteApp() {notes = new ArrayList<>();loadNotes();setTitle("桌面便签");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setResizable(false);setLayout(new BorderLayout());setSize(400, 500);JPanel titleBar = new JPanel();titleBar.setBackground(Color.GRAY);titleBar.setLayout(new BorderLayout());JLabel titleLabel = new JLabel("桌面便签");titleLabel.setForeground(Color.WHITE);titleLabel.setHorizontalAlignment(SwingConstants.CENTER);titleBar.add(titleLabel, BorderLayout.CENTER);titleBar.addMouseListener(new MouseAdapter() {public void mousePressed(MouseEvent e) {initialClick = e.getPoint();getComponentAt(initialClick);}});titleBar.addMouseMotionListener(new MouseAdapter() {public void mouseDragged(MouseEvent e) {int thisX = getLocation().x;int thisY = getLocation().y;int xMoved = e.getX() - initialClick.x;int yMoved = e.getY() - initialClick.y;int x = thisX + xMoved;int y = thisY + yMoved;setLocation(x, y);}});add(titleBar, BorderLayout.NORTH);noteTextArea = new JTextArea();noteTextArea.setLineWrap(true);noteTextArea.setFont(new Font("微软雅黑", Font.PLAIN, 14));JScrollPane scrollPane = new JScrollPane(noteTextArea);scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);add(scrollPane, BorderLayout.CENTER);JPanel buttonPanel = new JPanel();buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));JButton newButton = new JButton("新增");newButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String note = noteTextArea.getText();notes.add(note);saveNotes();noteTextArea.setText("");}});buttonPanel.add(newButton);JButton historyButton = new JButton("查看历史");historyButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {StringBuilder history = new StringBuilder();for (String note : notes) {history.append(note).append("\n");}JOptionPane.showMessageDialog(null, history.toString(), "便签历史", JOptionPane.INFORMATION_MESSAGE);}});buttonPanel.add(historyButton);add(buttonPanel, BorderLayout.SOUTH);pack();setLocationRelativeTo(null);setAlwaysOnTop(true);setVisible(true);}private void loadNotes() {try {File file = new File("notes.txt");if (file.exists()) {BufferedReader reader = new BufferedReader(new FileReader(file));String line;while ((line = reader.readLine()) != null) {notes.add(line);}reader.close();}} catch (IOException e) {e.printStackTrace();}}private void saveNotes() {try {BufferedWriter writer = new BufferedWriter(new FileWriter("notes.txt"));for (String note : notes) {writer.write(note);writer.newLine();}writer.close();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {@Overridepublic void run() {new DesktopNoteApp();}});}
}
在这个修改后的代码中,我添加了一个标题栏titleBar,并在标题栏上添加了一个JLabel用于显示标题。我还添加了鼠标事件监听器,以实现窗口的拖动功能。最后,我调用了setAlwaysOnTop(true)方法,将窗口置于顶层。
运行效果
置顶了,但是大小没起作用
我: setSize(400, 500);不起作用
chatgpt: 抱歉,我之前的回答有误。在这种情况下,您可以使用setPreferredSize(new Dimension(400, 500))方法来设置窗口的大小。请将以下代码添加到构造函数的setSize(400, 500)之后:
setPreferredSize(new Dimension(400, 500));
pack();
这将确保窗口的大小为400x500像素。
运行效果
我: titleLabel这里高度调高一点,因为现在这样不好看,而且可拖动区域太小了
chatgpt: 要调整titleLabel的高度,您可以在titleBar的布局中添加一个BorderLayout.NORTH约束,并将titleLabel添加到该约束中。然后,您可以使用setPreferredSize(new Dimension(400, 30))方法来设置titleLabel的高度。请将以下代码添加到构造函数的titleBar设置之后:
titleBar.add(titleLabel, BorderLayout.NORTH);
titleLabel.setPreferredSize(new Dimension(400, 30));
这将使titleLabel的高度为30像素,并将其放置在titleBar的顶部。
运行效果
我: 然后文本区域我希望有一点内外边距,这样文字就不是紧挨着边框了
chatgpt: 要为文本区域添加内外边距,您可以使用setMargin(new Insets(top, left, bottom, right))方法来设置边距。请将以下代码添加到构造函数的noteTextArea设置之后:
noteTextArea.setMargin(new Insets(10, 10, 10, 10));
这将为文本区域的上、左、下、右边添加10像素的边距。您可以根据需要调整边距的大小。
运行效果
我: 我想把titleLabel去掉,因为窗口title是桌面便签,现在又额外加个label显示桌面便签,感觉很多余
chatgpt: 如果您想要去掉titleLabel,您可以直接将titleBar设置为窗口的标题栏。请将以下代码添加到构造函数的titleBar设置之后:
setUndecorated(true);
这将去掉窗口的标题栏,并使titleBar成为窗口的顶部区域。这样,您就不需要额外的titleLabel来显示标题了。
运行效果
我: 右键titleBar,弹出右键菜单,右键菜单项有”关闭“
chatgpt: 要将右键菜单添加到titleBar上,并在菜单中添加一个"关闭"菜单项,您可以使用JPopupMenu和JMenuItem来实现。请将以下代码添加到构造函数的titleBar设置之后:
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem closeMenuItem = new JMenuItem("关闭");
closeMenuItem.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {dispose();}
});
popupMenu.add(closeMenuItem);titleBar.addMouseListener(new MouseAdapter() {public void mousePressed(MouseEvent e) {if (e.isPopupTrigger()) {popupMenu.show(e.getComponent(), e.getX(), e.getY());}}public void mouseReleased(MouseEvent e) {if (e.isPopupTrigger()) {popupMenu.show(e.getComponent(), e.getX(), e.getY());}}
});
这将在titleBar上添加一个右键菜单,并在菜单中添加一个"关闭"菜单项。当用户右键单击titleBar时,将显示右键菜单,并且当用户选择"关闭"菜单项时,窗口将被关闭。
运行效果
我: 启动后,点击查看历史按钮,整个窗口卡住了不能点了。
chatgpt: 这是因为在点击"查看历史"按钮时,您使用了JOptionPane.showMessageDialog来显示历史弹窗,但是由于该方法是阻塞的,它会阻止用户与窗口进行交互。为了解决这个问题,您可以使用JDialog来创建一个非阻塞的自定义弹窗。请将以下代码添加到构造函数的historyButton的ActionListener中:
historyButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {JDialog historyDialog = new JDialog();historyDialog.setTitle("便签历史");historyDialog.setModal(true);historyDialog.setResizable(false);historyDialog.setLayout(new BorderLayout());historyDialog.setPreferredSize(new Dimension(500, 400));JTextArea historyTextArea = new JTextArea();historyTextArea.setEditable(false);historyTextArea.setFont(new Font("微软雅黑", Font.PLAIN, 14));historyTextArea.setMargin(new Insets(15, 15, 15, 15));JScrollPane scrollPane = new JScrollPane(historyTextArea);scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);historyDialog.add(scrollPane, BorderLayout.CENTER);StringBuilder history = new StringBuilder();for (String note : notes) {history.append(note).append("\n");}historyTextArea.setText(history.toString());historyDialog.pack();historyDialog.setAlwaysOnTop(true);historyDialog.setLocationRelativeTo(null);historyDialog.setVisible(true);}
});
这将创建一个非阻塞的自定义弹窗,其中包含一个JTextArea用于显示历史内容。当用户点击"查看历史"按钮时,将显示该弹窗,并将历史内容显示在JTextArea中。这样,用户就可以同时与窗口进行交互和查看历史内容。
运行效果
。。。。。。
之后,我又让它给我设置窗口透明度,增加系统托盘(右键托盘弹出close菜单,退出应用程序);
然后继新增、查看历史按钮后,又分别让它加了清空、删除两个按钮。其中清空是清空当前面板中的内容,就像新增,点击新增也会清空当前面板内容,只不过新增会先将内容保存再清空。删除则不仅是清空当前面板中的内容,还会将历史内容给全部清空。
经过多次询问和调整,最后的效果感觉还可以哈哈哈
最后,我将代码打包,然后用工具转成了exe程序,我发现程序一运行,任务栏会有图标显示(这个图标不是指的托盘图标),如下图:
这样肯定不行啊,我想让窗口一直显示在桌面,但是任务栏我不想让它显示这个图标,只显示托盘图标,我去问gpt,可是我发现我不知道该怎么给它描述,导致它给的答案牛头不对马嘴。后面我尝试把 JFrame 改成 JDialog 完美解决😎😎
2023.06.30更新:
1、增加双击窗口时可以隐藏窗口,只显示一个小图标在桌面上,再次双击小图标可再次显示便签窗口;
2、增加自定义更改窗口透明度、字体大小、小图标;
3、查看历史弹窗修改,去掉标题栏等,双击弹窗关闭;
4、增加便签窗口贴边时可以自动隐藏,只显示小图标;(这个功能有点小问题,所以我把代码注释了)
下面是最后的完整代码
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;public class DesktopNoteApp extends JDialog {private List<String> notes = new ArrayList<>();private JTextArea noteTextArea;private Point initialClick;private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();// 获取屏幕的大小// 当前内容,当窗口被隐藏时,记录文本域的当前内容,当窗口再次显示,将内容重新赋值给文本域private String currentContent = "";// 默认的窗口透明度,分别是便签窗口和历史记录窗口private float opacity1 = 0.5f,opacity2 = 0.5f;// 默认的字体大小,分别是便签窗口和历史记录窗口private int fontSize1 = 14,fontSize2 = 14;// 默认的图标弹窗的图标路径private String iconDialogPath = "img\\1.png";public DesktopNoteApp() {loadNotes();// 先加载txt文件setUndecorated(true);// 去掉外面的边框修饰。setResizable(false);setLayout(new BorderLayout());setSize(300, 300);setPreferredSize(new Dimension(300, 300));setOpacity(opacity1);pack();// 标题栏面板JPanel titleBar = new JPanel();titleBar.setBackground(Color.decode("#6c768a"));titleBar.setLayout(new BorderLayout());JLabel titleLabel = new JLabel("桌面便签");titleLabel.setForeground(Color.WHITE);titleLabel.setHorizontalAlignment(SwingConstants.CENTER);titleBar.add(titleLabel, BorderLayout.NORTH);titleLabel.setPreferredSize(new Dimension(300, 30));// 鼠标动作监听器titleBar.addMouseMotionListener(new MouseAdapter() {// 鼠标拖动public void mouseDragged(MouseEvent e) {int thisX = getLocation().x;int thisY = getLocation().y;int xMoved = e.getX() - initialClick.x;int yMoved = e.getY() - initialClick.y;int x = thisX + xMoved;int y = thisY + yMoved;setLocation(x, y);}});// 当标题栏面板右键时,弹出菜单JPopupMenu popupMenu = popupMenu();// 鼠标监听事件titleBar.addMouseListener(new MouseAdapter() {// 鼠标按下public void mousePressed(MouseEvent e) {initialClick = e.getPoint();getComponentAt(initialClick);if (e.isPopupTrigger()) {popupMenu.show(e.getComponent(), e.getX(), e.getY());}if (e.getClickCount() == 2) { // 鼠标双击currentContent = noteTextArea.getText();setVisible(false);// 隐藏便签窗口iconDialog();// 显示图标}}// 鼠标松开public void mouseReleased(MouseEvent e) {if (e.isPopupTrigger()) {popupMenu.show(e.getComponent(), e.getX(), e.getY());}}});add(titleBar, BorderLayout.NORTH);// 文本域noteTextArea = new JTextArea();noteTextArea.setLineWrap(true);noteTextArea.setFont(new Font("微软雅黑", Font.PLAIN, fontSize1));noteTextArea.setMargin(new Insets(10, 20, 10, 20));noteTextArea.addMouseListener(new MouseAdapter() {// 鼠标双击public void mousePressed(MouseEvent e) {if (e.getClickCount() == 2) {currentContent = noteTextArea.getText();setVisible(false);// 隐藏便签窗口iconDialog();// 显示图标}}});// 文本域的滚动条JScrollPane scrollPane = new JScrollPane(noteTextArea);scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);add(scrollPane, BorderLayout.CENTER);// 下方的按钮面板JPanel buttonPanel = new JPanel();buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));buttonPanel.add(newButton()); // 新增按钮和它的事件buttonPanel.add(historyButton()); // 查看历史按钮和它的事件buttonPanel.add(clearButton()); // 清空所有便签内容按钮和它的事件buttonPanel.add(deleteButton()); // 删除所有历史便签内容和它的事件add(buttonPanel, BorderLayout.SOUTH);// 贴边隐藏窗口/*addComponentListener(new ComponentAdapter() {@Overridepublic void componentMoved(ComponentEvent e) {int x = getLocation().x;int y = getLocation().y;int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;if (x <= 0 || y <= 0 || x + getWidth() >= screenWidth || y + getHeight() >= screenHeight) {setVisible(false);// 隐藏便签窗口iconDialog();// 显示图标}}});*/pack();// 设置对话框的位置,位于屏幕右上角位置int x = screenSize.width - getWidth();setLocation(x-50, 50);setAlwaysOnTop(true);// 置于顶层,不会受win+d影响if (SystemTray.isSupported()) {addTrayIcon();}setVisible(true);}/*** 右键标题栏,弹出菜单*/private JPopupMenu popupMenu(){JPopupMenu popupMenu = new JPopupMenu();// 关闭菜单JMenuItem closeMenuItem = new JMenuItem("退出");closeMenuItem.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {dispose();// 释放窗口System.exit(0);// 关闭程序}});popupMenu.add(closeMenuItem);return popupMenu;}/*** 新增按钮和它的事件*/private JButton newButton(){JButton newButton = new JButton("新增");newButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String note = noteTextArea.getText();if (note.length()>0){Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String format = sdf.format(date);note = format + ":" + note;notes.add(note);saveNotes();noteTextArea.setText("");currentContent = "";}}});return newButton;}/*** 查看历史按钮和它的事件和它的事件*/private JButton historyButton(){JButton historyButton = new JButton("历史");historyButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {historyDialog();// 创建一个JDialog模态框}});return historyButton;}/*** 清空当前面板内容按钮和它的事件*/private JButton clearButton(){JButton clearButton = new JButton("清空");clearButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String msg = "是否要清空当前面板内容?\n\n清空后将不保存到历史记录中。";createConfirm("清空当前内容",msg,1);}});return clearButton;}/*** 删除所有历史便签内容和它的事件*/private JButton deleteButton(){JButton deleteButton = new JButton("删除");deleteButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String msg = "是否要删除所有便签内容?\n\n其中包括历史记录内容。";createConfirm("删除所有内容,包括历史记录",msg,2);}});return deleteButton;}/*** 创建一个是或否的对话框* @param title 对话框title* @param msg 对话框提示信息* @param type 1 清空当前对话框内容 2 清空当前对话框内容以及删除历史记录*/private void createConfirm(String title,String msg,int type){JDialog dialog = new JDialog();dialog.setTitle(title);dialog.setModal(true);dialog.setAlwaysOnTop(true);// 历史模态框置顶JOptionPane optionPane = new JOptionPane(msg, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);dialog.setContentPane(optionPane);optionPane.addPropertyChangeListener(new PropertyChangeListener() {@Overridepublic void propertyChange(PropertyChangeEvent evt) {String prop = evt.getPropertyName();if (dialog.isVisible() && (evt.getSource() == optionPane) && (prop.equals(JOptionPane.VALUE_PROPERTY))) {int result = (Integer) optionPane.getValue();if (result == JOptionPane.YES_OPTION) { // 执行清空操作noteTextArea.setText("");if (type == 2){notes.clear();clearNotes();}}dialog.dispose(); // 关闭对话框}}});int x = screenSize.width - getWidth();dialog.setLocation(x-50, 100);dialog.pack();dialog.setVisible(true);}/*** 添加系统托盘*/private void addTrayIcon(){SystemTray tray = SystemTray.getSystemTray();Image image = Toolkit.getDefaultToolkit().getImage("trayIcon.png");PopupMenu menu = new PopupMenu();MenuItem exitMenuItem = new MenuItem("exit");exitMenuItem.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.exit(0);}});menu.add(exitMenuItem);TrayIcon trayIcon = new TrayIcon(image, "桌面便签", menu);trayIcon.setImageAutoSize(true);try {tray.add(trayIcon);} catch (AWTException e) {e.printStackTrace();}}/*** 历史记录弹框*/private void historyDialog(){JDialog historyDialog = new JDialog();// 创建一个JDialog模态框historyDialog.setUndecorated(true);historyDialog.setOpacity(opacity2);// 这个要设置setUndecorated(true)才起作用historyDialog.setTitle("便签历史");historyDialog.setModal(true);// 设置为模态对话框,这样就不允许与其他窗口交互,只能先关闭这个窗口才能操作其他窗口historyDialog.setResizable(false);historyDialog.setLayout(new BorderLayout());historyDialog.setSize(400, 300);historyDialog.setPreferredSize(new Dimension(400, 300));// 显示历史内容的文本域JTextArea historyTextArea = new JTextArea();historyTextArea.setEditable(false);historyTextArea.setFont(new Font("微软雅黑", Font.PLAIN, fontSize2));historyTextArea.setMargin(new Insets(15, 15, 15, 15));// 文本域的滚动条JScrollPane scrollPane = new JScrollPane(historyTextArea);scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);historyDialog.add(scrollPane, BorderLayout.CENTER);// 读取历史内容并设置到文本域中StringBuilder history = new StringBuilder();for (String note : notes) {history.append(note).append("\n\n");}historyTextArea.setText(history.toString());// 鼠标动作监听器historyTextArea.addMouseMotionListener(new MouseAdapter() {// 鼠标拖动public void mouseDragged(MouseEvent e) {int thisX = historyDialog.getLocation().x;int thisY = historyDialog.getLocation().y;int xMoved = e.getX() - initialClick.x;int yMoved = e.getY() - initialClick.y;int x = thisX + xMoved;int y = thisY + yMoved;historyDialog.setLocation(x, y);}});historyTextArea.addMouseListener(new MouseAdapter() {// 鼠标双击隐藏public void mousePressed(MouseEvent e) {initialClick = e.getPoint();historyDialog.getComponentAt(initialClick);if (e.getClickCount() == 2) {historyDialog.setVisible(false);}}});// 设置对话框的位置,位于屏幕右上角位置int x = screenSize.width - getWidth();historyDialog.setLocation(x-50, 50);historyDialog.pack();historyDialog.setAlwaysOnTop(true);// 历史模态框置顶historyDialog.setVisible(true);}/*** 图标弹框*/private void iconDialog(){JDialog iconDialog = new JDialog();ImageIcon icon=new ImageIcon(iconDialogPath);//图片的路径int iconWidth = icon.getIconWidth()/2;int iconHeight = icon.getIconHeight()/2;iconDialog.setUndecorated(true);// 去掉外面的边框修饰。iconDialog.setResizable(false);iconDialog.setBackground(new Color(0,0,0,0));//背景透明iconDialog.setLayout(new BorderLayout());iconDialog.setSize(iconWidth,iconHeight);iconDialog.setPreferredSize(new Dimension(iconWidth, iconHeight));// 设置对话框的位置,位于屏幕右上角位置int x = screenSize.width - getWidth();iconDialog.setLocation(x+150, 50);iconDialog.setAlwaysOnTop(true);// 置于顶层,不会受win+d影响//添加图片JLabel label=new JLabel();icon.setImage(icon.getImage().getScaledInstance(iconWidth, iconHeight, Image.SCALE_AREA_AVERAGING));label.setBounds(getX(), getY(), iconWidth, iconHeight);label.setSize(iconWidth,iconHeight);label.setIcon(icon);iconDialog.add(label);// 鼠标动作监听器iconDialog.addMouseMotionListener(new MouseAdapter() {// 鼠标拖动public void mouseDragged(MouseEvent e) {int thisX = iconDialog.getLocation().x;int thisY = iconDialog.getLocation().y;int xMoved = e.getX() - initialClick.x;int yMoved = e.getY() - initialClick.y;int x = thisX + xMoved;int y = thisY + yMoved;iconDialog.setLocation(x, y);}});iconDialog.addMouseListener(new MouseAdapter() {@Overridepublic void mousePressed(MouseEvent e) {initialClick = e.getPoint();iconDialog.getComponentAt(initialClick);if (e.getClickCount() == 2) {iconDialog.setVisible(false);//隐藏图标窗口noteTextArea.setText(currentContent);//设置文本域内容setVisible(true);//显示便签窗口}}});iconDialog.setVisible(true);}/*** 加载保存的文件*/private void loadNotes() {try {File file = new File("notes.txt");FileInputStream fis = null;InputStreamReader isr = null;BufferedReader reader = null;if (file.exists()) {fis= new FileInputStream(file);isr=new InputStreamReader(fis,"utf-8");reader = new BufferedReader(isr);String line;while ((line = reader.readLine()) != null) {notes.add(line);}reader.close();isr.close();fis.close();}File setFile = new File("set.txt");if (setFile.exists()) {fis= new FileInputStream(setFile);isr=new InputStreamReader(fis,"utf-8");reader = new BufferedReader(isr);String line;while ((line = reader.readLine()) != null) {if (line.length()>0){String s = line.split("=")[1];s = s.trim();if (line.startsWith("便签窗口透明度")) opacity1 = (float) Double.parseDouble(s);if (line.startsWith("历史窗口透明度")) opacity1 = (float) Double.parseDouble(s);if (line.startsWith("便签窗口字体大小")) fontSize1 = Integer.parseInt(s);if (line.startsWith("历史窗口字体大小")) fontSize2 = Integer.parseInt(s);if (line.startsWith("图标弹窗图标路径")) iconDialogPath = s;}}reader.close();isr.close();fis.close();}} catch (IOException e) {e.printStackTrace();}}/*** 将内容保存到txt文件中*/private void saveNotes() {try {BufferedWriter writer = new BufferedWriter(new FileWriter("notes.txt"));for (String note : notes) {writer.write(note);writer.newLine();}writer.flush();writer.close();} catch (IOException e) {e.printStackTrace();}}/*** 将txt文件中的内容全部清空*/private void clearNotes() {try {BufferedWriter writer = new BufferedWriter(new FileWriter("notes.txt"));writer.write("");writer.flush();writer.close();} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) {SwingUtilities.invokeLater(new Runnable() {@Overridepublic void run() {new DesktopNoteApp();}});}
}
然后最后打包的目录结构是这样的:
这样我们就通过gpt实现了一个简易的桌面便签😎这个自己用用还是可以的,虽然界面简陋了点,但是基本功能还是有的。
给个我自己的使用效果:
这个是便签窗口
这个是双击便签窗口后隐藏,只显示小图标在桌面上的样子
打包的exe我放到这里了:下载