我: 用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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public void actionPerformed(ActionEvent e) {
dispose();// 释放窗口
System.exit(0);// 关闭程序
}
});
popupMenu.add(closeMenuItem);
return popupMenu;
}
/**
* 新增按钮和它的事件
*/
private JButton newButton(){
JButton newButton = new JButton("新增");
newButton.addActionListener(new ActionListener() {
@Override
public 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() {
@Override
public void actionPerformed(ActionEvent e) {
historyDialog();// 创建一个JDialog模态框
}
});
return historyButton;
}
/**
* 清空当前面板内容按钮和它的事件
*/
private JButton clearButton(){
JButton clearButton = new JButton("清空");
clearButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String msg = "是否要清空当前面板内容?\n\n清空后将不保存到历史记录中。";
createConfirm("清空当前内容",msg,1);
}
});
return clearButton;
}
/**
* 删除所有历史便签内容和它的事件
*/
private JButton deleteButton(){
JButton deleteButton = new JButton("删除");
deleteButton.addActionListener(new ActionListener() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public void run() {
new DesktopNoteApp();
}
});
}
}
然后最后打包的目录结构是这样的:
这样我们就通过gpt实现了一个简易的桌面便签😎这个自己用用还是可以的,虽然界面简陋了点,但是基本功能还是有的。
给个我自己的使用效果:
这个是便签窗口
这个是双击便签窗口后隐藏,只显示小图标在桌面上的样子
打包的exe我放到这里了:下载