一、redis-desktop-manager(使用Java Swing类手写 Redis可视化工具 最好用的Redis可视化工具)
pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sk.redis.desktop.manager</groupId>
<artifactId>redis-desktop-manager</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
</dependencies>
</project>
项目结构介绍
基础包为com.sk.redis.desktop.manager
core包
DataBase 类
package com.sk.redis.desktop.manager.core;
import redis.clients.jedis.Jedis;
import java.util.Set;
/**
* 数据库类
*/
public class DataBase {
//数据库的索引
private Integer dataBaseName;
public DataBase(Integer index) {
this.dataBaseName = index;
}
//获取数据库下所有的key名字
public Set<String> getKeyNames(Jedis jedis) {
jedis.select(dataBaseName);
return jedis.keys("*");
}
//获取数据库的容量
public Long getDBSize(Jedis jedis) {
jedis.select(dataBaseName);
return jedis.dbSize();
}
//获取数据库节点的标题
public String getNodeTitle(Jedis jedis) {
return "db" + dataBaseName + "(" + getDBSize(jedis) + ")";
}
//修建node节点名
public static String buildNodeTitle(Integer dbIndex, String num) {
return "db" + dbIndex + "(" + num + ")";
}
//通过node节点名获取数据库索引
public static Integer getNodeTitleNum(String nodeTitle) {
return Integer.parseInt(nodeTitle.substring(nodeTitle.indexOf("(") + 1, nodeTitle.indexOf(")")));
}
//通过数据节点获取数据库的索引号
public static Integer getNodeTitleIndex(String nodeTitle) {
return Integer.parseInt(nodeTitle.substring(nodeTitle.indexOf("b") + 1, nodeTitle.indexOf("(")));
}
}
MyIcon 类
package com.sk.redis.desktop.manager.core;
import com.sk.redis.desktop.manager.tool.ResourceTool;
import javax.swing.*;
import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* 图标类
*/
public class MyIcon implements Serializable {
public Map<String, ImageIcon> map = new HashMap<>();
//添加图标
public void putIcon(String iconName, ImageIcon icon) {
map.put(iconName, icon);
}
//获取图标
public ImageIcon getIcon(String iconName) {
return map.get(iconName);
}
public static void main(String[] args) {
//用于快速把图片对象持久化出来用于反编译
MyIcon myIcon = new MyIcon();
File file = new File("E:\\IDEA\\project\\redis-desktop-manager\\src\\main\\resources\\image");
String[] list = file.list();
for (String name : list) {
if (name.split("\\.")[0].equals("add-connection") || name.split("\\.")[0].equals("setting") || name.split("\\.")[0].equals("save") || name.split("\\.")[0].equals("cancel")) {
myIcon.putIcon(name.split("\\.")[0], ResourceTool.getICon("image/" + name, 25, 25));
continue;
}
myIcon.putIcon(name.split("\\.")[0], ResourceTool.getICon("image/" + name, 16, 16));
}
ResourceTool.saveObject(myIcon, "E:\\IDEA\\project\\redis-desktop-manager\\src\\main\\resources\\icon\\icon.dat");
}
}
Redis 类
package com.sk.redis.desktop.manager.core;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Redis数据库对象
*/
public class Redis {
private String name = "127.0.0.1";
private String ip = "127.0.0.1";
private Integer port = 6379;
private String passWord = "";
private Jedis jedis;
public String getName() {
return name;
}
public String getIp() {
return ip;
}
public Integer getPort() {
return port;
}
public String getPassWord() {
return passWord;
}
public Jedis getJedis() {
return jedis;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Redis redis = (Redis) o;
return Objects.equals(name, redis.name) && Objects.equals(ip, redis.ip) && Objects.equals(port, redis.port) && Objects.equals(passWord, redis.passWord) && Objects.equals(jedis, redis.jedis);
}
//因为要存进Map集合建议重写HASHCode方法
@Override
public int hashCode() {
return Objects.hash(name, ip, port, passWord, jedis);
}
//有密码创建
public Redis(String name, String ip, Integer port, String passWord) {
this.name = name;
this.ip = ip;
this.port = port;
this.passWord = passWord;
this.jedis = new Jedis(this.ip, this.port);
this.jedis.auth(this.passWord);
}
//无密码创建
public Redis(String name, String ip, Integer port) {
this.name = name;
this.ip = ip;
this.port = port;
this.jedis = new Jedis(this.ip, this.port);
}
//无参代表默认值
public Redis() {
this.jedis = new Jedis(this.ip, this.port);
}
//获取redis下所有的数据库对象
public List<DataBase> getDataBases() {
List<DataBase> dataBases = new ArrayList<>();
for (int i = 0; i < 16; i++) {
dataBases.add(new DataBase(i));
}
return dataBases;
}
//关闭连接
public void close() {
name = null;
ip = null;
port = null;
passWord = null;
jedis.close();
jedis = null;
Runtime.getRuntime().gc();
}
}
exception包
ExceptionMessage 类
package com.sk.redis.desktop.manager.core;
import redis.clients.jedis.Jedis;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Redis数据库对象
*/
public class Redis {
private String name = "127.0.0.1";
private String ip = "127.0.0.1";
private Integer port = 6379;
private String passWord = "";
private Jedis jedis;
public String getName() {
return name;
}
public String getIp() {
return ip;
}
public Integer getPort() {
return port;
}
public String getPassWord() {
return passWord;
}
public Jedis getJedis() {
return jedis;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Redis redis = (Redis) o;
return Objects.equals(name, redis.name) && Objects.equals(ip, redis.ip) && Objects.equals(port, redis.port) && Objects.equals(passWord, redis.passWord) && Objects.equals(jedis, redis.jedis);
}
//因为要存进Map集合建议重写HASHCode方法
@Override
public int hashCode() {
return Objects.hash(name, ip, port, passWord, jedis);
}
//有密码创建
public Redis(String name, String ip, Integer port, String passWord) {
this.name = name;
this.ip = ip;
this.port = port;
this.passWord = passWord;
this.jedis = new Jedis(this.ip, this.port);
this.jedis.auth(this.passWord);
}
//无密码创建
public Redis(String name, String ip, Integer port) {
this.name = name;
this.ip = ip;
this.port = port;
this.jedis = new Jedis(this.ip, this.port);
}
//无参代表默认值
public Redis() {
this.jedis = new Jedis(this.ip, this.port);
}
//获取redis下所有的数据库对象
public List<DataBase> getDataBases() {
List<DataBase> dataBases = new ArrayList<>();
for (int i = 0; i < 16; i++) {
dataBases.add(new DataBase(i));
}
return dataBases;
}
//关闭连接
public void close() {
name = null;
ip = null;
port = null;
passWord = null;
jedis.close();
jedis = null;
Runtime.getRuntime().gc();
}
}
HashKeyExitsException 类
package com.sk.redis.desktop.manager.exception;
/**
*hash类型键已存在错误(用于插入新值时检测是否键已存在,如果存在则报错)
*/
public class HashKeyExitsException extends Exception {
public HashKeyExitsException(String hashKey) {
super("【" + ExceptionMessage.getMessage(hashKey) + "】键已存在!");
}
}
HashKeyNotExitsException 类
package com.sk.redis.desktop.manager.exception;
/**
* hash类型键不存在错误(用于删除键时检测键是否存在,如果不存在则报错)
*/
public class HashKeyNotExitsException extends Exception {
public HashKeyNotExitsException(String hashKey) {
super("【" + ExceptionMessage.getMessage(hashKey) + "】键不存在!");
}
}
KeyExistException 类
package com.sk.redis.desktop.manager.exception;
/**
* key已存在,用于添加新key时检测,如果已经存在同名key则报错
*/
public class KeyExistException extends Exception {
public KeyExistException(String keyName) {
super("【" + ExceptionMessage.getMessage(keyName) + "】键已存在");
}
}
KeyNotExitsException 类
package com.sk.redis.desktop.manager.exception;
/**
* key不存在,用于删除、修改、插入、重命名、设置ttl、删除行、删除列等功能执行前检测,如果不存在则报错
*/
public class KeyNotExitsException extends Exception {
public KeyNotExitsException(String keyName) {
super("【" + ExceptionMessage.getMessage(keyName) + "】key不存在!");
}
}
front包
dialog包
ConnInfoDialog 类
package com.sk.redis.desktop.manager.front.dialog;
import com.sk.redis.desktop.manager.core.Redis;
import com.sk.redis.desktop.manager.front.Main;
import javax.swing.*;
import java.awt.*;
/**
* 连接信息弹窗
*/
public class ConnInfoDialog extends JDialog {
private Main main;
private JTextField nameText;
private JTextField ipText;
private JTextField verifyText;
private JTextField portText;
public ConnInfoDialog(Main main) {
super(main, true);
this.main = main;
setSize(400, 400);
setLayout(null);
setLocationRelativeTo(null);
setTitle("新连接设置");
setResizable(false);
init();
setVisible(true);
}
void init() {
Font font = new Font("微软雅黑", Font.BOLD, 20);
JLabel name = new JLabel("名字:");
name.setBounds(20, 40, 50, 30);
name.setFont(font);
add(name);
nameText = new JTextField("127.0.0.1");
nameText.setBounds(70, 40, 300, 30);
nameText.setToolTipText("连接名");
nameText.setFont(font);
add(nameText);
JLabel ip = new JLabel("地址:");
ip.setBounds(20, 90, 50, 30);
ip.setFont(font);
add(ip);
ipText = new JTextField("127.0.0.1");
ipText.setBounds(70, 90, 300, 30);
ipText.setFont(font);
add(ipText);
JLabel verify = new JLabel("验证:");
verify.setBounds(20, 140, 50, 30);
verify.setFont(font);
add(verify);
verifyText = new JTextField();
verifyText.setBounds(70, 140, 300, 30);
verifyText.setToolTipText("(可选) Redis 服务器验证密码");
verifyText.setFont(font);
add(verifyText);
JLabel port = new JLabel("端口:");
port.setBounds(20, 190, 50, 30);
port.setFont(font);
add(port);
portText = new JTextField("6379");
portText.setBounds(70, 190, 300, 30);
portText.setFont(font);
add(portText);
JButton connBtn = new JButton("连接");
connBtn.setFont(font);
connBtn.setFocusable(false);
connBtn.setBounds((400 - 200) / 2, 270, 200, 50);
connBtn.addActionListener(e -> {
String nameVal = nameText.getText().trim();
String ipVal = ipText.getText().trim();
String portVal = portText.getText().trim();
String verifyVal = verifyText.getText().trim();
if (check(nameVal, ipVal, portVal)) {
try {
if (verifyVal.equals("")) {
if (main.getMainPanel().getTreePanel().isRepetition(nameVal)) {
JOptionPane.showMessageDialog(this, "连接名不可以重复!");
return;
}
main.getMainPanel().getTreePanel().addOrUpdate(new Redis(nameVal, ipVal, Integer.parseInt(portVal)));
} else {
main.getMainPanel().getTreePanel().addOrUpdate(new Redis(nameVal, ipVal, Integer.parseInt(portVal), verifyVal));
}
dispose();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, "连接失败!请检查你的连接信息。");
}
}
});
add(connBtn);
}
boolean check(String nameVal, String ipVal, String portVal) {
if (nameVal.equals("")) {
JOptionPane.showMessageDialog(this, "连接失败!名字不可以为空。");
return false;
}
if (ipVal.equals("")) {
JOptionPane.showMessageDialog(this, "连接失败!地址不可以为空。");
return false;
}
if (portVal.equals("")) {
JOptionPane.showMessageDialog(this, "连接失败!,端口号不可以为空。");
return false;
}
return true;
}
}
CreateKeyDialog 类
package com.sk.redis.desktop.manager.front.dialog;
import com.sk.redis.desktop.manager.exception.KeyExistException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.filter.DoubleOnlyFilter;
import com.sk.redis.desktop.manager.info.KeyInfo;
import com.sk.redis.desktop.manager.tool.ResourceTool;
import javax.swing.*;
import javax.swing.text.AbstractDocument;
import java.awt.*;
/**
* 创建key的弹窗
*/
public class CreateKeyDialog extends JDialog {
private Main main;
private JComboBox<String> comboBox;
private Font font = new Font("微软雅黑", Font.PLAIN, 16);
private JTextField keyNameText;
private JLabel scoreOrKey;
private JScrollPane scoreOrKeyTextScroll;
private JTextPane scoreOrKeyText;
private JLabel value;
private JScrollPane valueTextScroll;
private JTextPane valueText;
private Box current;
private JButton save;
private JButton cancel;
public CreateKeyDialog(Main main) {
super(main, true);
this.main = main;
setSize(400, 500);
setMinimumSize(new Dimension(400, 500));
setLocationRelativeTo(null);
setTitle("新建key");
setIconImage(ResourceTool.getImage("image/key.png"));
init();
initListener();
setVisible(true);
}
void init() {
scoreOrKey = new JLabel();
scoreOrKey.setFont(font);
scoreOrKeyText = new JTextPane();
scoreOrKeyText.setFont(font);
scoreOrKeyTextScroll = new JScrollPane(scoreOrKeyText);
value = new JLabel("Value:");
value.setFont(font);
valueText = new JTextPane();
valueText.setFont(font);
valueTextScroll = new JScrollPane(valueText);
Box keyNameAndType = Box.createVerticalBox();
Box keyNameLabelBox = Box.createHorizontalBox();
JLabel keyNameLabel = new JLabel("键 名:");
keyNameLabel.setFont(font);
keyNameLabelBox.add(keyNameLabel);
keyNameLabelBox.add(Box.createHorizontalGlue());
keyNameText = new JTextField();
keyNameText.setFont(font);
Box typeLabelBox = Box.createHorizontalBox();
JLabel typeLabel = new JLabel("类 型:");
typeLabel.setFont(font);
typeLabelBox.add(typeLabel);
typeLabelBox.add(Box.createHorizontalGlue());
comboBox = new JComboBox<>(new String[]{"string", "list", "set", "zset", "hash"});
comboBox.setBackground(Color.WHITE);
comboBox.setFont(font);
//添加到keyNameAndType容器中
keyNameAndType.add(Box.createVerticalStrut(10));
keyNameAndType.add(keyNameLabelBox);
keyNameAndType.add(Box.createVerticalStrut(5));
keyNameAndType.add(keyNameText);
keyNameAndType.add(Box.createVerticalStrut(5));
keyNameAndType.add(typeLabelBox);
keyNameAndType.add(Box.createVerticalStrut(5));
keyNameAndType.add(comboBox);
//添加的窗口容器中
add(keyNameAndType, BorderLayout.NORTH);
current = getStringListSetBox();
add(current, BorderLayout.CENTER);
Box btnBox = Box.createHorizontalBox();
save = new JButton("保存");
save.setFont(font);
save.setIcon(Main.ICON.getIcon("save"));
save.setBackground(Color.WHITE);
cancel = new JButton("取消");
cancel.setFont(font);
cancel.setIcon(Main.ICON.getIcon("cancel"));
cancel.setBackground(Color.WHITE);
btnBox.add(Box.createHorizontalGlue());
btnBox.add(cancel);
btnBox.add(Box.createHorizontalStrut(5));
btnBox.add(save);
btnBox.add(Box.createHorizontalStrut(15));
add(btnBox, BorderLayout.SOUTH);
}
Box getStringListSetBox() {
Box stringListSet = Box.createVerticalBox();
Box valueLabel = Box.createHorizontalBox();
valueLabel.add(value);
valueLabel.add(Box.createHorizontalGlue());
Box valueText = Box.createHorizontalBox();
valueText.add(valueTextScroll);
stringListSet.add(Box.createVerticalStrut(5));
stringListSet.add(valueLabel);
stringListSet.add(Box.createVerticalStrut(5));
stringListSet.add(valueText);
stringListSet.add(Box.createVerticalStrut(5));
return stringListSet;
}
Box getZSetHashBox(String typeName) {
Box zSetHashBox = Box.createVerticalBox();
Box valueLabel1 = Box.createHorizontalBox();
if (typeName.equals("hash")) {
scoreOrKey.setText("Key:");
AbstractDocument document = (AbstractDocument) scoreOrKeyText.getDocument();
document.setDocumentFilter(null);
} else {
scoreOrKey.setText("Score:");
AbstractDocument document = (AbstractDocument) scoreOrKeyText.getDocument();
document.setDocumentFilter(new DoubleOnlyFilter());
}
valueLabel1.add(scoreOrKey);
valueLabel1.add(Box.createHorizontalGlue());
Box valueText1 = Box.createHorizontalBox();
valueText1.add(scoreOrKeyTextScroll);
Box valueLabel2 = Box.createHorizontalBox();
valueLabel2.add(value);
valueLabel2.add(Box.createHorizontalGlue());
Box valueText2 = Box.createHorizontalBox();
valueText2.add(valueTextScroll);
zSetHashBox.add(Box.createVerticalStrut(5));
zSetHashBox.add(valueLabel1);
zSetHashBox.add(Box.createVerticalStrut(5));
zSetHashBox.add(valueText1);
zSetHashBox.add(Box.createVerticalStrut(5));
zSetHashBox.add(valueLabel2);
zSetHashBox.add(Box.createVerticalStrut(5));
zSetHashBox.add(valueText2);
zSetHashBox.add(Box.createVerticalStrut(5));
return zSetHashBox;
}
void initListener() {
comboBox.addActionListener(e -> {
String type = comboBox.getSelectedItem().toString();
remove(current);
if (type.equals("string") || type.equals("list") || type.equals("set")) {
current = getStringListSetBox();
} else {
valueText.setText("");
scoreOrKeyText.setText("");
current = getZSetHashBox(type);
}
add(current, BorderLayout.CENTER);
this.validate();
});
save.addActionListener(e -> {
String type = comboBox.getSelectedItem().toString();
String keyName = keyNameText.getText();
String scoreKey = scoreOrKeyText.getText();
String value = valueText.getText();
KeyInfo keyInfo = new KeyInfo(keyName, type, scoreKey, value);
try {
main.getMainPanel().getTreePanel().addKey(keyInfo);
dispose();
} catch (KeyExistException ex) {
JOptionPane.showMessageDialog(this, ex.getMessage());
}
});
cancel.addActionListener(e -> {
dispose();
});
}
}
ListSetInsertDialog 类
package com.sk.redis.desktop.manager.front.dialog;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.show.ListSetInsert;
import com.sk.redis.desktop.manager.front.show.TemplatePanel;
import javax.swing.*;
import java.awt.*;
/**
* list类型 和 set类型的插入数据的弹窗
*/
public class ListSetInsertDialog extends JDialog {
private Main main;
private ListSetInsert listSetPanel;
public ListSetInsertDialog(Main main, ListSetInsert listSetPanel) {
super(main, true);
this.main = main;
this.listSetPanel = listSetPanel;
setIconImage(Main.ICON.getIcon("add-line").getImage());
setLayout(new BorderLayout());
Font font = new Font("微软雅黑", Font.PLAIN, 16);
setSize(400, 500);
setTitle("添加");
setLocationRelativeTo(null);
Box top = Box.createHorizontalBox();
JLabel jLabel = new JLabel("Value:");
jLabel.setFont(font);
top.add(jLabel);
top.add(Box.createHorizontalGlue());
add(top, BorderLayout.NORTH);
JTextPane textPane = new JTextPane();
textPane.setFont(font);
JScrollPane textPaneScroll = new JScrollPane(textPane);
add(textPaneScroll, BorderLayout.CENTER);
Box bottom = Box.createHorizontalBox();
JButton cancel = new JButton("取消");
cancel.addActionListener(e -> {
dispose();
});
cancel.setBackground(Color.WHITE);
cancel.setFont(font);
JButton add = new JButton("添加");
add.addActionListener(e -> {
String text = textPane.getText();
try {
listSetPanel.insertLine(text);
dispose();
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(main.getMainPanel(), ex.getMessage());
TemplatePanel tem = (TemplatePanel) listSetPanel;
tem.clearNode();
dispose();
}
});
add.setBackground(Color.WHITE);
add.setFont(font);
bottom.add(Box.createHorizontalGlue());
bottom.add(cancel);
bottom.add(Box.createHorizontalStrut(10));
bottom.add(add);
bottom.add(Box.createHorizontalStrut(20));
add(bottom, BorderLayout.SOUTH);
setVisible(true);
}
}
ZSetHashInsertDialog 类
package com.sk.redis.desktop.manager.front.dialog;
import com.sk.redis.desktop.manager.exception.HashKeyExitsException;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.filter.DoubleOnlyFilter;
import com.sk.redis.desktop.manager.front.show.TemplatePanel;
import com.sk.redis.desktop.manager.front.show.ZSetHashInsert;
import com.sk.redis.desktop.manager.front.show.ZSetPanel;
import javax.swing.*;
import javax.swing.text.AbstractDocument;
import java.awt.*;
/**
* zset类型 和 hash类型 插入数据的弹窗
*/
public class ZSetHashInsertDialog extends JDialog {
public Main main;
public ZSetHashInsert zSetHashPanel;
public ZSetHashInsertDialog(Main main, ZSetHashInsert zSetHashPanel) {
super(main, true);
this.main = main;
this.zSetHashPanel = zSetHashPanel;
setIconImage(Main.ICON.getIcon("add-line").getImage());
setLayout(new BorderLayout());
Font font = new Font("微软雅黑", Font.PLAIN, 16);
setSize(400, 500);
setLocationRelativeTo(null);
setTitle("添加");
Box body = Box.createVerticalBox();
Box title1 = Box.createHorizontalBox();
JLabel keyOrScore1 = new JLabel();
keyOrScore1.setFont(font);
title1.add(keyOrScore1);
title1.add(Box.createHorizontalGlue());
JTextPane text1 = new JTextPane();
text1.setFont(font);
JScrollPane textScroll1 = new JScrollPane(text1);
Box title2 = Box.createHorizontalBox();
JLabel keyOrScore2 = new JLabel("Value:");
keyOrScore2.setFont(font);
title2.add(keyOrScore2);
title2.add(Box.createHorizontalGlue());
JTextPane text2 = new JTextPane();
text2.setFont(font);
JScrollPane textScroll2 = new JScrollPane(text2);
body.add(title1);
body.add(textScroll1);
body.add(title2);
body.add(textScroll2);
add(body, BorderLayout.CENTER);
Box bottom = Box.createHorizontalBox();
JButton cancel = new JButton("取消");
cancel.addActionListener(e -> {
dispose();
});
cancel.setBackground(Color.WHITE);
cancel.setFont(font);
JButton add = new JButton("添加");
add.addActionListener(e -> {
try {
zSetHashPanel.insertLine(text1.getText(), text2.getText());
dispose();
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(this, ex.getMessage());
TemplatePanel tem = (TemplatePanel) zSetHashPanel;
tem.clearNode();
dispose();
} catch (HashKeyExitsException ex) {
JOptionPane.showMessageDialog(this, ex.getMessage());
}
});
add.setBackground(Color.WHITE);
add.setFont(font);
bottom.add(Box.createHorizontalGlue());
bottom.add(cancel);
bottom.add(Box.createHorizontalStrut(10));
bottom.add(add);
bottom.add(Box.createHorizontalStrut(20));
add(bottom, BorderLayout.SOUTH);
if (zSetHashPanel instanceof ZSetPanel) {
keyOrScore1.setText("Score:");
AbstractDocument document = (AbstractDocument) text1.getDocument();
document.setDocumentFilter(new DoubleOnlyFilter());
} else {
keyOrScore1.setText("Key:");
}
setVisible(true);
}
}
filter包
DoubleOnlyFilter 类
package com.sk.redis.desktop.manager.front.filter;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import java.util.regex.Pattern;
/**
* 只能是数字类型的过滤器用于 zset类型的 score值的插入和修改
*/
public class DoubleOnlyFilter extends DocumentFilter {
// 正则表达式
private final Pattern pattern = Pattern.compile("^[0-9]*\\.?[0-9]*$");
@Override
public void insertString(FilterBypass fb, int offset, String string,
AttributeSet attr) throws BadLocationException {
if (string == null) {
return;
}
String newValue = fb.getDocument().getText(0, fb.getDocument().getLength()) + string;
if (pattern.matcher(newValue).matches()) {
super.insertString(fb, offset, string, attr);
}
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text,
AttributeSet attrs) throws BadLocationException {
if (text == null) {
return;
}
String newValue = fb.getDocument().getText(0, fb.getDocument().getLength())
.substring(0, offset) + text
+ fb.getDocument().getText(offset + length, fb.getDocument().getLength() - offset - length);
if (pattern.matcher(newValue).matches()) {
super.replace(fb, offset, length, text, attrs);
}
}
}
panel包
MainPanel 类
package com.sk.redis.desktop.manager.front.panel;
import com.sk.redis.desktop.manager.front.Main;
import javax.swing.*;
/**
* 主面板
*/
public class MainPanel extends JSplitPane {
//主窗口对象
private Main main;
//树状面板
private TreePanel treePanel;
//展示面板
private ShowPanel showPanel;
public MainPanel(Main main) {
//创建水平分割动态调节的模式
super(JSplitPane.HORIZONTAL_SPLIT);
this.main = main;
initComponent();
//设置面板的调节分割线的位置
setDividerLocation(250);
//设置分割钱的宽度
setDividerSize(5);
}
//初始化组件
private void initComponent() {
treePanel = new TreePanel(this);
add(treePanel);
showPanel = new ShowPanel(this);
add(showPanel);
}
//获取主窗口
public Main getMain() {
return main;
}
//获取树状面板
public TreePanel getTreePanel() {
return treePanel;
}
//获取数据展示面板
public ShowPanel getShowPanel() {
return showPanel;
}
}
MenuPanel 类
package com.sk.redis.desktop.manager.front.panel;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.dialog.ConnInfoDialog;
import javax.swing.*;
import java.awt.*;
/**
* Main的菜单面板类
* 功能1.添加Redis连接按钮
* 功能2.添加设置按钮
*/
public class MenuPanel extends JPanel {
//Main面板对象
private Main main;
//添加Redis连接按钮
private JButton conn;
public MenuPanel(Main main) {
this.main = main;
setLayout(new BorderLayout());
initComponent();
}
void initComponent() {
//使用Box的静态方法创建一个水平容器
Box box = Box.createHorizontalBox();
//为了布局效果,添加一个10像素的空白,
box.add(Box.createHorizontalStrut(10));
conn = createBtn("连接到 Redis 服务器");
conn.setIcon(Main.ICON.getIcon("add-connection"));
conn.setBackground(Color.WHITE);
conn.addActionListener(e -> {
//创建创建连接对象对话框
new ConnInfoDialog(main);
});
box.add(conn);
box.add(Box.createHorizontalGlue());
box.add(Box.createHorizontalStrut(10));
add(box);
}
//因为菜单按钮统一格式所以有此方法
JButton createBtn(String name) {
JButton jButton = new JButton(name);
jButton.setFont(new Font("微软雅黑", Font.PLAIN, 18));
jButton.setFocusable(false);
return jButton;
}
}
ShowPanel 类
package com.sk.redis.desktop.manager.front.panel;
import com.sk.redis.desktop.manager.front.show.*;
import com.sk.redis.desktop.manager.info.ShowInfo;
import javax.swing.*;
import java.awt.*;
public class ShowPanel extends JPanel {
private MainPanel mainPanel;
private ListPanel listPanel;
private StringPanel stringPanel;
private SetPanel setPanel;
private ZSetPanel zSetPanel;
private HashPanel hashPanel;
private TemplatePanel current;
public ShowPanel(MainPanel mainPanel) {
this.mainPanel = mainPanel;
setLayout(new BorderLayout());
new Thread(() -> {
stringPanel = new StringPanel(this);
}).start();
new Thread(() -> {
listPanel = new ListPanel(this);
}).start();
new Thread(() -> {
setPanel = new SetPanel(this);
}).start();
new Thread(() -> {
zSetPanel = new ZSetPanel(this);
}).start();
new Thread(() -> {
hashPanel = new HashPanel(this);
}).start();
}
public void showPanel(ShowInfo showInfo) {
if (current != null) {
removeAll();
}
switch (showInfo.getType()) {
case "STRING":
current = stringPanel;
break;
case "LIST":
current = listPanel;
break;
case "SET":
current = setPanel;
break;
case "ZSET":
current = zSetPanel;
break;
case "HASH":
current = hashPanel;
break;
}
current.showData(showInfo);
add(current, BorderLayout.CENTER);
updateUI();
}
public MainPanel getMainPanel() {
return mainPanel;
}
}
TreePanel 类
package com.sk.redis.desktop.manager.front.panel;
import com.sk.redis.desktop.manager.core.DataBase;
import com.sk.redis.desktop.manager.core.Redis;
import com.sk.redis.desktop.manager.exception.KeyExistException;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.dialog.CreateKeyDialog;
import com.sk.redis.desktop.manager.info.KeyInfo;
import com.sk.redis.desktop.manager.info.ShowInfo;
import com.sk.redis.desktop.manager.tool.RedisTool;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
public class TreePanel extends JScrollPane {
private MainPanel mainPanel;
//树对象
private JTree tree;
//根节点对象
private DefaultMutableTreeNode root;
//用于存储1级节点的redis的对象,所有的一级节点是我们的连接对象
private Map<String, Redis> redisMap;
private JPopupMenu pop;
private JMenuItem refresh;
private JMenuItem createKey;
private JMenuItem copyName;
private JMenuItem delAll;
private JMenuItem delConn;
public TreePanel(MainPanel mainPanel) {
this.mainPanel = mainPanel;
this.redisMap = new HashMap<>();
initPopupMenu();
//初始化树
initTree();
//添加所有监听
addListener();
//读取连接信息文件
// addConnectionInfo();
//把树设置进入滑动面板
setViewportView(tree);
//更新数据
validate();
}
private void initPopupMenu() {
pop = new JPopupMenu();
refresh = new JMenuItem("刷新");
refresh.setIcon(Main.ICON.getIcon("refresh"));
refresh.addActionListener(e -> {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getSelectionPath().getLastPathComponent();
if (node.getLevel() == 1) {
Redis redis = redisMap.get(node.toString());
root.remove(node);
root.add(getConnectionNode(redis));
updateTreeUI();
} else if (node.getLevel() == 2) {
Redis redis = redisMap.get(node.getParent().toString());
node.removeAllChildren();
DataBase dataBase = new DataBase(DataBase.getNodeTitleIndex(node.toString()));
node.setUserObject(dataBase.getNodeTitle(redis.getJedis()));
getKeysNodes(redis, dataBase).forEach(node::add);
updateTreeUI();
} else if (node.getLevel() == 3) {
DefaultMutableTreeNode dataBaseNode = (DefaultMutableTreeNode) node.getParent();
Redis redis = redisMap.get(dataBaseNode.getParent().toString());
try {
ShowInfo showInfo = new ShowInfo(redis, dataBaseNode, node);
mainPanel.getShowPanel().showPanel(showInfo);
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(mainPanel, ex.getMessage());
dataBaseNode.remove(node);
String nodeTitle = dataBaseNode.toString();
Integer dbIndex = DataBase.getNodeTitleIndex(nodeTitle);
Integer num = DataBase.getNodeTitleNum(nodeTitle);
dataBaseNode.setUserObject(DataBase.buildNodeTitle(dbIndex, String.valueOf(num - 1)));
updateTreeUI();
}
}
});
createKey = new JMenuItem("新建Key");
createKey.setIcon(Main.ICON.getIcon("add-key"));
createKey.addActionListener(e -> {
new CreateKeyDialog(mainPanel.getMain());
});
copyName = new JMenuItem("复制名字");
copyName.setIcon(Main.ICON.getIcon("copy"));
copyName.addActionListener(e -> {
String text = tree.getSelectionPath().getLastPathComponent().toString();
StringSelection selection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, null);
});
delAll = new JMenuItem("清除全部");
delAll.setIcon(Main.ICON.getIcon("clear"));
delAll.addActionListener(e -> {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getSelectionPath().getLastPathComponent();
if (node.getLevel() == 1) {
Redis redis = redisMap.get(node.toString());
RedisTool.flushAll(redis);
root.remove(node);
root.add(getConnectionNode(redis));
updateTreeUI();
mainPanel.getShowPanel().removeAll();
mainPanel.getShowPanel().updateUI();
} else if (node.getLevel() == 2) {
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) ((DefaultMutableTreeNode) tree.getSelectionPath().getLastPathComponent()).getParent();
Integer dbIndex = DataBase.getNodeTitleIndex(node.toString());
Redis redis = redisMap.get(parent.toString());
RedisTool.flushDb(redis, dbIndex);
node.setUserObject(new DataBase(dbIndex).getNodeTitle(redis.getJedis()));
node.removeAllChildren();
updateTreeUI();
mainPanel.getShowPanel().removeAll();
mainPanel.getShowPanel().updateUI();
}
});
delConn = new JMenuItem("删除连接");
delConn.setIcon(Main.ICON.getIcon("delete-line"));
delConn.addActionListener(e -> {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getSelectionPath().getLastPathComponent();
root.remove(node);
String key = node.toString();
Redis redis = redisMap.get(key);
redis.close();
redisMap.remove(key, redis);
updateTreeUI();
});
pop.add(refresh);
pop.add(createKey);
pop.add(copyName);
pop.add(delAll);
pop.add(delConn);
}
// private void addConnectionInfo() {
// Properties prop = ResourceTool.getConnectionProperties();
// String[] name = prop.getProperty("redis.name").split(",");
// String[] ip = prop.getProperty("redis.ip").split(",");
// String[] port = prop.getProperty("redis.port").split(",");
// String[] passWord = prop.getProperty("redis.passWord").split(",");
// for (int i = 0; i < ip.length; i++) {
// if (!ip[i].equals("null")) {
// String p = passWord[i].equals("null") ? "" : passWord[i];
// try {
// Redis redis;
// if (p.equals("")) {
// redis = new Redis(name[i], ip[i], Integer.valueOf(port[i]));
// } else {
// redis = new Redis(name[i], ip[i], Integer.valueOf(port[i]), p);
// }
// addOrUpdate(redis);
// } catch (Exception e) {
// continue;
// }
// }
// }
// }
private void initTree() {
//创建根节点
root = new DefaultMutableTreeNode("root");
//创建树
tree = new JTree(root);
//设置树的节点字体
tree.setFont(new Font("微软雅黑", Font.PLAIN, 16));
//隐藏树根节点
tree.setRootVisible(false);
//设置树的样式
tree.setCellRenderer(new TreePanelStyle());
}
private void addListener() {
tree.addTreeSelectionListener(e -> {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.getPath().getLastPathComponent();
if (node.getLevel() == 3) {
DefaultMutableTreeNode dataBaseNode = (DefaultMutableTreeNode) node.getParent();
String connName = dataBaseNode.getParent().toString();
try {
ShowInfo showInfo = new ShowInfo(redisMap.get(connName), dataBaseNode, node);
//判断key是否存在,存在进入到展示环节,不存在就在树中删除掉key节点并移除展示页面
if (RedisTool.exitsKey(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName())) {
mainPanel.getShowPanel().showPanel(showInfo);
} else {
JOptionPane.showMessageDialog(mainPanel, "【" + showInfo.getKeyName() + "】Key不存在!");
dataBaseNode.remove(node);
mainPanel.getShowPanel().removeAll();
mainPanel.getShowPanel().updateUI();
updateTreeUI();
}
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(mainPanel, ex.getMessage());
dataBaseNode.remove(node);
updateTreeUI();
}
}
});
tree.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
TreePath node = tree.getPathForLocation(e.getX(), e.getY());
if (node != null) {
//选中节点
tree.setSelectionPath(node);
DefaultMutableTreeNode currNode = (DefaultMutableTreeNode) node.getLastPathComponent();
if (currNode.getLevel() == 1) {
createKey.setVisible(false);
delConn.setVisible(true);
delAll.setVisible(true);
refresh.setVisible(true);
copyName.setVisible(true);
copyName.setVisible(true);
} else if (currNode.getLevel() == 2) {
delConn.setVisible(false);
createKey.setVisible(true);
refresh.setVisible(true);
copyName.setVisible(true);
delAll.setVisible(true);
} else if (currNode.getLevel() == 3) {
delConn.setVisible(false);
delAll.setVisible(false);
createKey.setVisible(false);
refresh.setVisible(true);
copyName.setVisible(true);
}
pop.show(tree, e.getX(), e.getY());
}
}
}
});
}
//判断树的节点名字是否有重复的
public boolean isRepetition(String name) {
for (int i = 0; i < root.getChildCount(); i++) {
if (root.getChildAt(i).toString().equals(name)) {
return true;
}
}
return false;
}
//添加新的连接对象的节点
public void addOrUpdate(Redis redis) {
DefaultMutableTreeNode connectionNode = getConnectionNode(redis);
root.add(connectionNode);
redisMap.put(connectionNode.toString(), redis);
tree.setModel(new DefaultTreeModel(root));
updateTreeUI();
}
//获取新连接对象的节点树
private DefaultMutableTreeNode getConnectionNode(Redis redis) {
DefaultMutableTreeNode connectionNode = new DefaultMutableTreeNode(redis.getName());
List<DataBase> dataBases = redis.getDataBases();
dataBases.forEach(dataBase -> connectionNode.add(getDataBaseNode(redis, dataBase)));
return connectionNode;
}
//获取每个数据库的节点
private DefaultMutableTreeNode getDataBaseNode(Redis redis, DataBase dataBase) {
String nodeTitle = dataBase.getNodeTitle(redis.getJedis());
DefaultMutableTreeNode dataBaseNode = new DefaultMutableTreeNode(nodeTitle);
getKeysNodes(redis, dataBase).forEach(dataBaseNode::add);
return dataBaseNode;
}
//获取数据库下所有key的节点
Set<DefaultMutableTreeNode> getKeysNodes(Redis redis, DataBase dataBase) {
return dataBase.getKeyNames(redis.getJedis()).stream().map(DefaultMutableTreeNode::new).collect(Collectors.toSet());
}
//更新树的UI
public void updateTreeUI() {
SwingUtilities.invokeLater(() -> tree.updateUI());
}
//获取redisMap对象
public Map<String, Redis> getRedisMap() {
return redisMap;
}
//添加key的方法
public void addKey(KeyInfo keyInfo) throws KeyExistException {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) Objects.requireNonNull(tree.getSelectionPath()).getLastPathComponent();
DefaultMutableTreeNode parent = (DefaultMutableTreeNode) tree.getSelectionPath().getParentPath().getLastPathComponent();
Integer dbIndex = DataBase.getNodeTitleIndex(node.toString());
Redis redis = redisMap.get(parent.toString());
if (RedisTool.exitsKey(redis, dbIndex, keyInfo.getKeyName())) {
throw new KeyExistException(keyInfo.getKeyName());
}
if (keyInfo.getType().equals("string")) {
RedisTool.addStringKey(redis, dbIndex, keyInfo.getKeyName(), keyInfo.getValue());
} else if (keyInfo.getType().equals("list")) {
RedisTool.addListKey(redis, dbIndex, keyInfo.getKeyName(), keyInfo.getValue());
} else if (keyInfo.getType().equals("set")) {
RedisTool.addSetKey(redis, dbIndex, keyInfo.getKeyName(), keyInfo.getValue());
} else if (keyInfo.getType().equals("zset")) {
RedisTool.addZSetKey(redis, dbIndex, keyInfo.getKeyName(), Double.parseDouble(keyInfo.getScoreOrKey()), keyInfo.getValue());
} else if (keyInfo.getType().equals("hash")) {
RedisTool.addHashKey(redis, dbIndex, keyInfo.getKeyName(), keyInfo.getScoreOrKey(), keyInfo.getValue());
} else {
return;
}
DataBase dataBase = new DataBase(dbIndex);
node.removeAllChildren();
node.setUserObject(dataBase.getNodeTitle(redis.getJedis()));
Set<DefaultMutableTreeNode> keysNodes = getKeysNodes(redis, dataBase);
keysNodes.forEach(node::add);
updateTreeUI();
for (DefaultMutableTreeNode keysNode : keysNodes) {
if (keysNode.getUserObject().toString().equals(keyInfo.getKeyName())) {
tree.setSelectionPath(new TreePath(keysNode));
break;
}
}
updateTreeUI();
}
}
//树的样式类
class TreePanelStyle extends DefaultTreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (value instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
//1级菜单是连接对象,2级菜单是数据库,3级菜单是key,所以设置key的节点图标
if (node.isLeaf() && node.getLevel() == 3) {
setIcon(Main.ICON.getIcon("key"));
} else {
//设置除了3级菜单以外的所有节点的节点图标
setIcon(Main.ICON.getIcon("database"));
}
}
return this;
}
}
show包
HashPanel 类
package com.sk.redis.desktop.manager.front.show;
import com.sk.redis.desktop.manager.exception.ExceptionMessage;
import com.sk.redis.desktop.manager.exception.HashKeyExitsException;
import com.sk.redis.desktop.manager.exception.HashKeyNotExitsException;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.dialog.ZSetHashInsertDialog;
import com.sk.redis.desktop.manager.front.panel.ShowPanel;
import com.sk.redis.desktop.manager.info.ShowInfo;
import com.sk.redis.desktop.manager.tool.RedisTool;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import static javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS;
public class HashPanel extends TemplatePanel implements ZSetHashInsert {
private JTable table;
private JTextField search;
private JLabel viewAsLabel1;
private JComboBox<String> comboBox1;
private JLabel valueLabel2;
private JLabel viewAsLabel2;
private JComboBox<String> comboBox2;
private JTextPane textPane2;
private JTextPane textPane1;
private final String[] columnNames = {"row", "key", "value"};
private String key = null;
private String value = null;
private String[][] currData;
private String comBoxSelect1 = "Text";
private String comBoxSelect2 = "Text";
private JButton insertBtn;
private JButton deleteBtn;
public HashPanel(ShowPanel showPanel) {
super(showPanel, true);
initTopPanel();
initCenterPanel();
initBottomPanel();
initListener();
}
@Override
void initCenterPanel() {
JSplitPane centerPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
centerPanel.setDividerLocation(130);
centerPanel.setDividerSize(5);
Box centerTopBox = Box.createHorizontalBox();
table = new JTable();
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JTableHeader tableHeader = table.getTableHeader();
Font font = new Font("微软雅黑", Font.PLAIN, 16);
tableHeader.setFont(font);
tableHeader.setReorderingAllowed(false);
table.setFont(font);
table.setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS);
JScrollPane tableScroll = new JScrollPane(table);
Box funcBox = Box.createVerticalBox();
insertBtn = new JButton("插入行");
insertBtn.setBackground(Color.CYAN);
insertBtn.setBorder(BorderFactory.createEmptyBorder(5, 64, 5, 64));
insertBtn.setIcon(Main.ICON.getIcon("add-line"));
insertBtn.setFocusable(false);
setFontSize(insertBtn, 16);
deleteBtn = new JButton("删除行");
deleteBtn.setBackground(Color.PINK);
deleteBtn.setBorder(BorderFactory.createEmptyBorder(5, 64, 5, 64));
deleteBtn.setIcon(Main.ICON.getIcon("delete-line"));
deleteBtn.setFocusable(false);
setFontSize(deleteBtn, 16);
search = new JTextField();
setFontSize(search, 16);
JPanel panel = new JPanel(new BorderLayout());
panel.add(search, BorderLayout.CENTER);
panel.setMaximumSize(new Dimension(400, search.getPreferredSize().height));
panel.setBackground(Color.BLACK);
funcBox.add(insertBtn);
funcBox.add(deleteBtn);
funcBox.add(panel);
funcBox.add(Box.createVerticalGlue());
centerTopBox.add(tableScroll);
centerTopBox.add(funcBox);
centerPanel.add(centerTopBox);
JSplitPane upDown = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
Box centerCenterBox1 = Box.createVerticalBox();
Box centerCenterLabelBox1 = Box.createHorizontalBox();
JLabel valueLabel1 = new JLabel("Key: " + '\u2193');
setFontSize(valueLabel1, 16);
viewAsLabel1 = new JLabel("View as: ");
setFontSize(viewAsLabel1, 16);
comboBox1 = new JComboBox<String>(new String[]{"Text", "JSON"});
setFontSize(comboBox1, 16);
centerCenterLabelBox1.add(valueLabel1);
centerCenterLabelBox1.add(Box.createHorizontalGlue());
centerCenterLabelBox1.add(viewAsLabel1);
centerCenterLabelBox1.add(comboBox1);
textPane1 = new JTextPane();
setFontSize(textPane1, 16);
JScrollPane textScroll1 = new JScrollPane(textPane1);
textScroll1.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
centerCenterBox1.add(centerCenterLabelBox1);
centerCenterBox1.add(textScroll1);
Box centerCenterBox2 = Box.createVerticalBox();
Box centerCenterLabelBox2 = Box.createHorizontalBox();
valueLabel2 = new JLabel("Value: " + '\u2193');
setFontSize(valueLabel2, 16);
viewAsLabel2 = new JLabel("View as: ");
setFontSize(viewAsLabel2, 16);
comboBox2 = new JComboBox<String>(new String[]{"Text", "JSON"});
setFontSize(comboBox2, 16);
centerCenterLabelBox2.add(valueLabel2);
centerCenterLabelBox2.add(Box.createHorizontalGlue());
centerCenterLabelBox2.add(viewAsLabel2);
centerCenterLabelBox2.add(comboBox2);
textPane2 = new JTextPane();
setFontSize(textPane2, 16);
JScrollPane textScroll2 = new JScrollPane(textPane2);
textScroll2.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
centerCenterBox2.add(centerCenterLabelBox2);
centerCenterBox2.add(textScroll2);
upDown.add(centerCenterBox1);
upDown.add(centerCenterBox2);
upDown.setDividerSize(5);
upDown.setDividerLocation(150);
centerPanel.add(upDown);
add(centerPanel, BorderLayout.CENTER);
}
@Override
void initListener() {
comboBox1.addActionListener(e -> {
comBoxSelect1 = (String) comboBox1.getSelectedItem();
setTextOrJson1();
});
comboBox2.addActionListener(e -> {
comBoxSelect2 = (String) comboBox2.getSelectedItem();
setTextOrJson2();
});
table.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
key = table.getValueAt(selectedRow, 1).toString();
value = table.getValueAt(selectedRow, 2).toString();
setTextOrJson1();
setTextOrJson2();
setUseState();
}
}
});
search.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
String text = search.getText().trim();
if (!text.equals("")) {
addOrUpdateTable(searchData(text));
}
}
@Override
public void removeUpdate(DocumentEvent e) {
String text = search.getText().trim();
if (text.equals("")) {
addOrUpdateTable(currData);
} else {
addOrUpdateTable(searchData(text));
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
insertBtn.addActionListener(e -> {
new ZSetHashInsertDialog(showPanel.getMainPanel().getMain(), this);
});
deleteBtn.addActionListener(e -> {
deleteLine();
});
save.addActionListener(e -> {
int row = table.getSelectedRow();
if (row != -1) {
try {
String newKey = textPane1.getText();
String newValue = textPane2.getText();
RedisTool.updateHash(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), key, newKey, newValue);
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "保存成功");
reloadTable();
selectRow(newKey);
} catch (HashKeyNotExitsException | HashKeyExitsException ex) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), ex.getMessage());
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), ex.getMessage());
clearNode();
}
}
});
}
@Override
void clearTextPanel() {
textPane1.setText("");
textPane2.setText("");
value = null;
key = null;
}
@Override
void setUseState() {
textPane1.setEnabled(true);
textPane2.setEnabled(true);
}
@Override
void setNoUseState() {
textPane1.setEnabled(false);
textPane2.setEnabled(false);
}
@Override
public void showData(ShowInfo showInfo) {
super.showInfo = showInfo;
super.setKeyType(showInfo.getType());
super.setKeyName(showInfo.getKeyName());
super.setTTl(String.valueOf(showInfo.getTtl()));
reloadTable();
super.setSize(String.valueOf(currData.length));
}
void reloadTable() {
try {
currData = RedisTool.getHashValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName());
setSize(String.valueOf(currData.length));
addOrUpdateTable(currData);
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
void addOrUpdateTable(String[][] data) {
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table.setModel(model);
clearTextPanel();
setNoUseState();
SwingUtilities.invokeLater(() -> {
table.updateUI();
});
}
String[][] searchData(String val) {
List<String[]> data = new ArrayList<>();
for (String[] currDatum : currData) {
if (currDatum[1].contains(val)) {
data.add(currDatum);
}
}
return data.toArray(new String[0][]);
}
void setTextOrJson1() {
if (key == null) {
return;
}
if (comBoxSelect1.equals("Text")) {
textPane1.setText(key);
} else {
String s = jsonFormat(key);
if (s != null) {
textPane1.setText(s);
} else {
textPane1.setText(key);
}
}
}
void setTextOrJson2() {
if (value == null) {
return;
}
if (comBoxSelect2.equals("Text")) {
textPane2.setText(value);
} else {
String s = jsonFormat(value);
if (s != null) {
textPane2.setText(s);
} else {
textPane2.setText(value);
}
}
}
public void selectRow(String value) {
for (int i = 0; i < currData.length; i++) {
if (currData[i][1].equals(value)) {
table.setRowSelectionInterval(i, i);
break;
}
}
}
@Override
public void insertLine(String scoreOrKey, String value) throws KeyNotExitsException, HashKeyExitsException {
RedisTool.addHash(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), scoreOrKey, value);
reloadTable();
selectRow(scoreOrKey);
}
private void deleteLine() {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
int i = JOptionPane.showConfirmDialog(showPanel.getMainPanel(), "确认删除【" + ExceptionMessage.getMessage(value) + "】吗?", "", 2);
if (i == 0) {
try {
RedisTool.delHashValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), key);
reloadTable();
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
} catch (HashKeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
}
}
}
}
}
ListPanel 类
package com.sk.redis.desktop.manager.front.show;
import com.sk.redis.desktop.manager.exception.ExceptionMessage;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.dialog.ListSetInsertDialog;
import com.sk.redis.desktop.manager.front.panel.ShowPanel;
import com.sk.redis.desktop.manager.info.ShowInfo;
import com.sk.redis.desktop.manager.tool.RedisTool;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import static javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS;
public class ListPanel extends TemplatePanel implements ListSetInsert {
//下拉列表
private JComboBox<String> comboBox;
//文本域
private JTextPane textPane;
//表格
private JTable table;
//列头
private final String[] columnNames = {"row", "value"};
//当前数据表格的数据,用于检索功能
private String[][] currData;
//用于保存点击列表行所显示的数据
private String value = null;
private String comBoxSelect = "Text";
//搜索框
private JTextField search;
//插入按钮
private JButton insertBtn;
private JButton deleteBtn;
public ListPanel(ShowPanel showPanel) {
super(showPanel, true);
initTopPanel();
initCenterPanel();
initBottomPanel();
initListener();
}
@Override
void initCenterPanel() {
JSplitPane centerPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
centerPanel.setDividerLocation(130);
centerPanel.setDividerSize(5);
Box centerTopBox = Box.createHorizontalBox();
table = new JTable();
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JTableHeader tableHeader = table.getTableHeader();
Font font = new Font("微软雅黑", Font.PLAIN, 16);
tableHeader.setFont(font);
tableHeader.setReorderingAllowed(false);
table.setFont(font);
table.setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS);
JScrollPane tableScroll = new JScrollPane(table);
Box funcBox = Box.createVerticalBox();
insertBtn = new JButton("插入行");
insertBtn.setBackground(Color.CYAN);
insertBtn.setBorder(BorderFactory.createEmptyBorder(5, 64, 5, 64));
insertBtn.setIcon(Main.ICON.getIcon("add-line"));
insertBtn.setFocusable(false);
setFontSize(insertBtn, 16);
deleteBtn = new JButton("删除行");
deleteBtn.setBackground(Color.PINK);
deleteBtn.setBorder(BorderFactory.createEmptyBorder(5, 64, 5, 64));
deleteBtn.setIcon(Main.ICON.getIcon("delete-line"));
deleteBtn.setFocusable(false);
setFontSize(deleteBtn, 16);
search = new JTextField();
setFontSize(search, 16);
JPanel panel = new JPanel(new BorderLayout());
panel.add(search, BorderLayout.CENTER);
panel.setMaximumSize(new Dimension(400, search.getPreferredSize().height));
panel.setBackground(Color.BLACK);
funcBox.add(insertBtn);
funcBox.add(deleteBtn);
funcBox.add(panel);
funcBox.add(Box.createVerticalGlue());
centerTopBox.add(tableScroll);
centerTopBox.add(funcBox);
centerPanel.add(centerTopBox);
Box centerCenterBox = Box.createVerticalBox();
Box centerCenterLabelBox = Box.createHorizontalBox();
JLabel valueLabel = new JLabel("Value: " + '\u2193');
setFontSize(valueLabel, 16);
JLabel viewAsLabel = new JLabel("View as: ");
setFontSize(viewAsLabel, 16);
comboBox = new JComboBox<>(new String[]{"Text", "JSON"});
setFontSize(comboBox, 16);
centerCenterLabelBox.add(valueLabel);
centerCenterLabelBox.add(Box.createHorizontalGlue());
centerCenterLabelBox.add(viewAsLabel);
centerCenterLabelBox.add(comboBox);
textPane = new JTextPane();
setFontSize(textPane, 16);
JScrollPane textScroll = new JScrollPane(textPane);
textScroll.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
centerCenterBox.add(centerCenterLabelBox);
centerCenterBox.add(textScroll);
centerPanel.add(centerCenterBox);
add(centerPanel, BorderLayout.CENTER);
}
@Override
void initListener() {
//下拉列表的选择点击事件
comboBox.addActionListener(e -> {
comBoxSelect = (String) comboBox.getSelectedItem();
setTextOrJson();
});
//表格的点击事件
table.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
value = table.getValueAt(selectedRow, 1).toString();
setTextOrJson();
setUseState();
}
}
});
//搜索框的文本变化事件
search.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
String text = search.getText().trim();
if (!text.equals("")) {
addOrUpdateTable(searchData(text));
}
}
@Override
public void removeUpdate(DocumentEvent e) {
String text = search.getText().trim();
if (text.equals("")) {
reloadTable();
} else {
addOrUpdateTable(searchData(text));
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
insertBtn.addActionListener(e -> {
new ListSetInsertDialog(showPanel.getMainPanel().getMain(), this);
});
deleteBtn.addActionListener(e -> {
deleteLine();
});
save.addActionListener(e -> {
int row = table.getSelectedRow();
if (row != -1) {
try {
RedisTool.updateList(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), row, textPane.getText());
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "保存成功");
reloadTable();
table.setRowSelectionInterval(row, row);
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), ex.getMessage());
clearNode();
}
}
});
}
@Override
void clearTextPanel() {
textPane.setText("");
value = null;
}
@Override
void setUseState() {
textPane.setEnabled(true);
}
@Override
void setNoUseState() {
textPane.setEnabled(false);
}
@Override
public void showData(ShowInfo showInfo) {
super.showInfo = showInfo;
super.setKeyType(showInfo.getType());
super.setKeyName(showInfo.getKeyName());
super.setTTl(String.valueOf(showInfo.getTtl()));
reloadTable();
super.setSize(String.valueOf(currData.length));
}
//重载表格(从数据库重新获取数据加载表格)
void reloadTable() {
try {
currData = RedisTool.getListValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName());
setSize(String.valueOf(currData.length));
addOrUpdateTable(currData);
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
//添加或更新表格方法
void addOrUpdateTable(String[][] data) {
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table.setModel(model);
clearTextPanel();
setNoUseState();
SwingUtilities.invokeLater(() -> {
table.updateUI();
});
}
//搜索方法
String[][] searchData(String val) {
List<String[]> data = new ArrayList<>();
for (String[] currDatum : currData) {
if (currDatum[1].contains(val)) {
data.add(currDatum);
}
}
return data.toArray(new String[0][]);
}
//设置富文本内容
void setTextOrJson() {
if (value == null) {
return;
}
if (comBoxSelect.equals("Text")) {
textPane.setText(value);
} else {
String s = jsonFormat(value);
if (s != null) {
textPane.setText(s);
} else {
textPane.setText(value);
}
textPane.setCaretPosition(0);
}
}
//插入一行方法
@Override
public void insertLine(String newValue) throws KeyNotExitsException {
RedisTool.addList(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), newValue);
reloadTable();
table.setRowSelectionInterval(currData.length - 1, currData.length - 1);
}
//删除一行方法
private void deleteLine() {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
int i = JOptionPane.showConfirmDialog(showPanel.getMainPanel(), "确认删除【" + ExceptionMessage.getMessage(value) + "】吗?", "", 2);
if (i == 0) {
try {
RedisTool.delListValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), value);
reloadTable();
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
}
}
}
ListSetInsert 类
package com.sk.redis.desktop.manager.front.show;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
/**
* list和set类型的panel实现此接口实现插入一行方法
*/
public interface ListSetInsert {
void insertLine(String newValue) throws KeyNotExitsException;
}
SetPanel 类
package com.sk.redis.desktop.manager.front.show;
import com.sk.redis.desktop.manager.exception.ExceptionMessage;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.dialog.ListSetInsertDialog;
import com.sk.redis.desktop.manager.front.panel.ShowPanel;
import com.sk.redis.desktop.manager.info.ShowInfo;
import com.sk.redis.desktop.manager.tool.RedisTool;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import static javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS;
public class SetPanel extends TemplatePanel implements ListSetInsert {
//下拉列表
private JComboBox<String> comboBox;
//文本域
private JTextPane textPane;
//表格
private JTable table;
//列头
private final String[] columnNames = {"row", "value"};
//当前数据表格的数据,用于检索功能
private String[][] currData;
//用于保存点击列表行所显示的数据
private String value = null;
private String comBoxSelect = "Text";
private JTextField search;
private JButton insertBtn;
private JButton deleteBtn;
public SetPanel(ShowPanel showPanel) {
super(showPanel, true);
initTopPanel();
initCenterPanel();
initBottomPanel();
initListener();
}
@Override
void initCenterPanel() {
JSplitPane centerPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
centerPanel.setDividerLocation(130);
centerPanel.setDividerSize(5);
Box centerTopBox = Box.createHorizontalBox();
table = new JTable();
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JTableHeader tableHeader = table.getTableHeader();
Font font = new Font("微软雅黑", Font.PLAIN, 16);
tableHeader.setFont(font);
tableHeader.setReorderingAllowed(false);
table.setFont(font);
table.setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS);
JScrollPane tableScroll = new JScrollPane(table);
Box funcBox = Box.createVerticalBox();
insertBtn = new JButton("插入行");
insertBtn.setBackground(Color.CYAN);
insertBtn.setBorder(BorderFactory.createEmptyBorder(5, 64, 5, 64));
insertBtn.setIcon(Main.ICON.getIcon("add-line"));
insertBtn.setFocusable(false);
setFontSize(insertBtn, 16);
deleteBtn = new JButton("删除行");
deleteBtn.setBackground(Color.PINK);
deleteBtn.setBorder(BorderFactory.createEmptyBorder(5, 64, 5, 64));
deleteBtn.setIcon(Main.ICON.getIcon("delete-line"));
deleteBtn.setFocusable(false);
setFontSize(deleteBtn, 16);
search = new JTextField();
setFontSize(search, 16);
JPanel panel = new JPanel(new BorderLayout());
panel.add(search, BorderLayout.CENTER);
panel.setMaximumSize(new Dimension(400, search.getPreferredSize().height));
panel.setBackground(Color.BLACK);
funcBox.add(insertBtn);
funcBox.add(deleteBtn);
funcBox.add(panel);
funcBox.add(Box.createVerticalGlue());
centerTopBox.add(tableScroll);
centerTopBox.add(funcBox);
centerPanel.add(centerTopBox);
Box centerCenterBox = Box.createVerticalBox();
Box centerCenterLabelBox = Box.createHorizontalBox();
JLabel valueLabel = new JLabel("Value: " + '\u2193');
setFontSize(valueLabel, 16);
JLabel viewAsLabel = new JLabel("View as: ");
setFontSize(viewAsLabel, 16);
comboBox = new JComboBox<>(new String[]{"Text", "JSON"});
setFontSize(comboBox, 16);
centerCenterLabelBox.add(valueLabel);
centerCenterLabelBox.add(Box.createHorizontalGlue());
centerCenterLabelBox.add(viewAsLabel);
centerCenterLabelBox.add(comboBox);
textPane = new JTextPane();
setFontSize(textPane, 16);
JScrollPane textScroll = new JScrollPane(textPane);
textScroll.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
centerCenterBox.add(centerCenterLabelBox);
centerCenterBox.add(textScroll);
centerPanel.add(centerCenterBox);
add(centerPanel, BorderLayout.CENTER);
}
@Override
void initListener() {
comboBox.addActionListener(e -> {
comBoxSelect = (String) comboBox.getSelectedItem();
setTextOrJson();
});
table.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
value = table.getValueAt(selectedRow, 1).toString();
setTextOrJson();
setUseState();
}
}
});
search.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
String text = search.getText().trim();
if (!text.equals("")) {
addOrUpdateTable(searchData(text));
}
}
@Override
public void removeUpdate(DocumentEvent e) {
String text = search.getText().trim();
if (text.equals("")) {
reloadTable();
} else {
addOrUpdateTable(searchData(text));
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
insertBtn.addActionListener(e -> {
new ListSetInsertDialog(showPanel.getMainPanel().getMain(), this);
});
deleteBtn.addActionListener(e -> {
deleteLine();
});
save.addActionListener(e -> {
int row = table.getSelectedRow();
if (row != -1) {
try {
String text = textPane.getText();
RedisTool.updateSet(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), value, text);
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "保存成功");
reloadTable();
selectRow(text);
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), ex.getMessage());
clearNode();
}
}
});
}
@Override
void clearTextPanel() {
textPane.setText("");
value = null;
}
@Override
void setUseState() {
textPane.setEnabled(true);
}
@Override
void setNoUseState() {
textPane.setEnabled(false);
}
@Override
public void showData(ShowInfo showInfo) {
this.showInfo = showInfo;
super.setKeyType(showInfo.getType());
super.setKeyName(showInfo.getKeyName());
super.setTTl(String.valueOf(showInfo.getTtl()));
reloadTable();
super.setSize(String.valueOf(currData.length));
}
void reloadTable() {
try {
currData = RedisTool.getSetValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName());
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
setSize(String.valueOf(currData.length));
addOrUpdateTable(currData);
}
void addOrUpdateTable(String[][] data) {
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table.setModel(model);
clearTextPanel();
setNoUseState();
SwingUtilities.invokeLater(() -> {
table.updateUI();
});
}
String[][] searchData(String val) {
List<String[]> data = new ArrayList<>();
for (String[] currDatum : currData) {
if (currDatum[1].contains(val)) {
data.add(currDatum);
}
}
return data.toArray(new String[0][]);
}
void setTextOrJson() {
if (value == null) {
return;
}
if (comBoxSelect.equals("Text")) {
textPane.setText(value);
} else {
String s = jsonFormat(value);
if (s != null) {
textPane.setText(s);
} else {
textPane.setText(value);
}
textPane.setCaretPosition(0);
}
}
@Override
public void insertLine(String newValue) throws KeyNotExitsException {
RedisTool.addSet(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), newValue);
reloadTable();
selectRow(newValue);
}
public void selectRow(String value) {
for (int i = 0; i < currData.length; i++) {
if (currData[i][1].equals(value)) {
table.setRowSelectionInterval(i, i);
break;
}
}
}
private void deleteLine() {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
int i = JOptionPane.showConfirmDialog(showPanel.getMainPanel(), "确认删除【" + ExceptionMessage.getMessage(value) + "】吗?", "", 2);
if (i == 0) {
try {
RedisTool.delSetValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), value);
reloadTable();
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
}
}
}
StringPanel 类
package com.sk.redis.desktop.manager.front.show;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.panel.ShowPanel;
import com.sk.redis.desktop.manager.info.ShowInfo;
import com.sk.redis.desktop.manager.tool.RedisTool;
import javax.swing.*;
import java.awt.*;
public class StringPanel extends TemplatePanel {
//展示数据的类型,Text和Json
private JComboBox<String> comboBox;
//富文本组件
private JTextPane textPane;
//默认数据展示为Text
private String comBoxSelect = "Text";
//当前在富文本中展示的值,用于保存按钮
private String value = null;
public StringPanel(ShowPanel showPanel) {
//false代表不使用table表格组件,所以不展示size标签
super(showPanel, false);
//初始化顶部面板
initTopPanel();
//初始化中心面板
initCenterPanel();
//初始化底部面板
initBottomPanel();
//初始化组件监听器
initListener();
}
@Override
void initCenterPanel() {
Box centerCenterBox = Box.createVerticalBox();
Box centerCenterLabelBox = Box.createHorizontalBox();
JLabel valueLabel = new JLabel("Value: " + '\u2193');
setFontSize(valueLabel, 16);
JLabel viewAsLabel = new JLabel("View as: ");
setFontSize(viewAsLabel, 16);
comboBox = new JComboBox<>(new String[]{"Text", "JSON"});
setFontSize(comboBox, 16);
centerCenterLabelBox.add(valueLabel);
centerCenterLabelBox.add(Box.createHorizontalGlue());
centerCenterLabelBox.add(viewAsLabel);
centerCenterLabelBox.add(comboBox);
textPane = new JTextPane();
setFontSize(textPane, 16);
JScrollPane textScroll = new JScrollPane(textPane);
textScroll.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
centerCenterBox.add(centerCenterLabelBox);
centerCenterBox.add(textScroll);
add(centerCenterBox, BorderLayout.CENTER);
}
@Override
void initListener() {
//下拉选择类型展示列表
comboBox.addActionListener(e -> {
comBoxSelect = (String) comboBox.getSelectedItem();
setTextOrJson();
});
//保存监听
save.addActionListener(e -> {
try {
RedisTool.updateString(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), textPane.getText());
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "保存成功");
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), ex.getMessage());
clearNode();
}
});
}
@Override
void clearTextPanel() {
textPane.setText("");
value = null;
}
@Override
void setUseState() {
}
@Override
void setNoUseState() {
}
//展示数据
@Override
public void showData(ShowInfo showInfo) {
super.showInfo = showInfo;
clearTextPanel();
super.setKeyType(showInfo.getType());
super.setKeyName(showInfo.getKeyName());
super.setTTl(String.valueOf(showInfo.getTtl()));
try {
value = RedisTool.getStringValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName());
setTextOrJson();
} catch (KeyNotExitsException e) {
clearNode();
}
}
//设置富文本展示为Text格式还是Json格式
void setTextOrJson() {
if (comBoxSelect.equals("Text")) {
textPane.setText(value);
} else {
String s = jsonFormat(value);
if (s != null) {
textPane.setText(s);
} else {
textPane.setText(value);
}
}
textPane.setCaretPosition(0);
}
}
TemplatePanel 类
package com.sk.redis.desktop.manager.front.show;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sk.redis.desktop.manager.core.DataBase;
import com.sk.redis.desktop.manager.exception.ExceptionMessage;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.panel.ShowPanel;
import com.sk.redis.desktop.manager.info.ShowInfo;
import com.sk.redis.desktop.manager.tool.RedisTool;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
/**
* 展示模板类(所有类型展示面板的共有部分组件)
*/
public abstract class TemplatePanel extends JPanel {
protected ShowPanel showPanel;
protected JLabel typeTop;
protected JTextField keyTop;
protected JLabel sizeTop;
protected JLabel ttlTop;
protected JButton renameTop;
protected JButton deleteTop;
protected JButton setTTLTop;
protected boolean hasTable;
protected ShowInfo showInfo;
protected JButton save;
public TemplatePanel(ShowPanel showPanel, boolean hasTable) {
this.showPanel = showPanel;
this.hasTable = hasTable;
setLayout(new BorderLayout());
UIManager.put("OptionPane.messageFont", new Font("微软雅黑", Font.PLAIN, 16));
UIManager.put("OptionPane.buttonFont", new Font("微软雅黑", Font.PLAIN, 16));
UIManager.put("TextField.font", new Font("微软雅黑", Font.PLAIN, 16));
UIManager.put("PasswordField.font", new Font("微软雅黑", Font.PLAIN, 16));
}
void initTopPanel() {
Box topBox = Box.createHorizontalBox();
typeTop = new JLabel("ZSET:");
setFontSize(typeTop, 16);
keyTop = new JTextField("zsetsize");
keyTop.setEditable(false);
setFontSize(keyTop, 16);
if (hasTable) {
sizeTop = new JLabel("Size: 123");
setFontSize(sizeTop, 16);
}
ttlTop = new JLabel("TTL: ");
setFontSize(ttlTop, 16);
renameTop = new JButton("重命名");
renameTop.setForeground(Color.blue);
renameTop.setIcon(Main.ICON.getIcon("rename"));
renameTop.addActionListener(e -> {
reNameKey();
});
renameTop.setBackground(Color.WHITE);
renameTop.setFocusable(false);
setFontSize(renameTop, 16);
deleteTop = new JButton("删除");
deleteTop.setForeground(Color.red);
deleteTop.addActionListener(e -> {
delKey();
});
deleteTop.setIcon(Main.ICON.getIcon("delete-line"));
deleteTop.setBackground(Color.WHITE);
deleteTop.setFocusable(false);
setFontSize(deleteTop, 16);
setTTLTop = new JButton("设置TTL");
setTTLTop.setForeground(Color.DARK_GRAY);
setTTLTop.setIcon(Main.ICON.getIcon("setting"));
setTTLTop.addActionListener(e -> {
settingTTL();
});
setTTLTop.setBackground(Color.WHITE);
setTTLTop.setFocusable(false);
setFontSize(setTTLTop, 16);
topBox.add(Box.createHorizontalStrut(10));
topBox.add(typeTop);
topBox.add(Box.createHorizontalStrut(5));
topBox.add(keyTop);
topBox.add(Box.createHorizontalStrut(10));
if (hasTable) {
topBox.add(sizeTop);
topBox.add(Box.createHorizontalStrut(10));
}
topBox.add(ttlTop);
topBox.add(Box.createHorizontalStrut(10));
topBox.add(renameTop);
topBox.add(Box.createHorizontalStrut(10));
topBox.add(deleteTop);
topBox.add(Box.createHorizontalStrut(10));
topBox.add(setTTLTop);
topBox.add(Box.createHorizontalStrut(10));
add(topBox, BorderLayout.NORTH);
}
void initBottomPanel() {
Box boxBottom = Box.createHorizontalBox();
save = new JButton("保存");
setFontSize(save, 20);
save.setBackground(Color.WHITE);
save.setForeground(new Color(180, 11, 221));
save.setIcon(Main.ICON.getIcon("save"));
boxBottom.add(Box.createHorizontalGlue());
boxBottom.add(save);
boxBottom.add(Box.createHorizontalStrut(20));
add(boxBottom, BorderLayout.SOUTH);
}
//设置类型的方法
void setKeyType(String typeName) {
typeTop.setText(typeName + ":");
}
//设置key名字的方法
void setKeyName(String keyName) {
keyTop.setText(keyName);
}
//设置list、set、hash、zset类型大小的方法
void setSize(String size) {
sizeTop.setText("Size: " + size);
}
//设置过期时间的方法
void setTTl(String ttl) {
ttlTop.setText("TTL: " + ttl);
}
//统一组件字体大小
void setFontSize(Component c, Integer size) {
Font font = c.getFont();
c.setFont(new Font(font.getName(), font.getStyle(), size));
}
//删除节点方法
public void clearNode() {
clearTextPanel();
showInfo.getDataBaseNode().setUserObject(new DataBase(showInfo.getDbIndex()).getNodeTitle(showInfo.getRedis().getJedis()));
showInfo.getDataBaseNode().remove(showInfo.getKeyNode());
showPanel.getMainPanel().getTreePanel().updateTreeUI();
showPanel.removeAll();
showPanel.updateUI();
}
//重命名方法
void reNameKey() {
String newName = JOptionPane.showInputDialog(showPanel.getMainPanel(), "新名字:", showInfo.getKeyName());
if (newName == null) {
return;
}
if (newName.equals("")) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "新名字不可以为空");
return;
}
try {
long res = RedisTool.keyRename(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), newName);
if (res != 0) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "修改成功");
setKeyName(newName);
showInfo.setKeyName(newName);
showInfo.getKeyNode().setUserObject(newName);
showPanel.getMainPanel().getTreePanel().updateTreeUI();
} else {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "修改失败");
}
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
//删除key的方法
void delKey() {
int res = JOptionPane.showConfirmDialog(showPanel.getMainPanel(), "确认删除【" + ExceptionMessage.getMessage(showInfo.getKeyName()) + "】?", "删除", JOptionPane.OK_CANCEL_OPTION);
if (res == 0) {
try {
long l = RedisTool.delKey(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName());
if (l != 0) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "【" + showInfo.getKeyName() + "】删除成功!");
long dataBaseSize = RedisTool.getDataBaseSize(showInfo.getRedis(), showInfo.getDbIndex());
showInfo.getDataBaseNode().setUserObject("db" + showInfo.getDbIndex() + "(" + dataBaseSize + ")");
clearNode();
} else {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "【" + showInfo.getKeyName() + "】删除失败!");
}
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
}
//设置过期时间的方法
void settingTTL() {
String newTTL = JOptionPane.showInputDialog(showPanel.getMainPanel(), "新的TTL:", showInfo.getTtl());
if (newTTL == null) {
return;
}
if (newTTL.equals("")) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "输入不可以为空");
return;
}
try {
long time = Long.parseLong(newTTL);
long res = RedisTool.setKeyTTL(showInfo.getRedis(), DataBase.getNodeTitleIndex(showInfo.getDataBaseNode().toString()), keyTop.getText(), time);
if (res != 0) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "修改成功");
setTTl(String.valueOf(time));
showInfo.setTtl(time);
} else {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "修改失败");
}
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "请输入数字");
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
//json格式化的方法
String jsonFormat(String text) {
ObjectMapper mapper = new ObjectMapper();
try {
Object object = mapper.readValue(text, Object.class);
String res = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
return text.replaceAll("\\s", "").length() == res.replaceAll("\\s", "").length() ? res : null;
} catch (IOException e) {
return null;
}
}
//初始化中心组件面板
abstract void initCenterPanel();
//初始化组件的监听
abstract void initListener();
//清除面板展示内容的方法
abstract void clearTextPanel();
//允许使用富文本
abstract void setUseState();
//不允许使用富文本
abstract void setNoUseState();
//展示数据方法
public abstract void showData(ShowInfo showInfo);
}
ZSetHashInsert 类
package com.sk.redis.desktop.manager.front.show;
import com.sk.redis.desktop.manager.exception.HashKeyExitsException;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
/**
* zset类型和hash类型插入的panel实现此接口实现插入一行方法
*/
public interface ZSetHashInsert {
void insertLine(String scoreOrKey, String value) throws KeyNotExitsException, HashKeyExitsException;
}
ZSetPanel 类
package com.sk.redis.desktop.manager.front.show;
import com.sk.redis.desktop.manager.exception.ExceptionMessage;
import com.sk.redis.desktop.manager.exception.HashKeyExitsException;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.front.Main;
import com.sk.redis.desktop.manager.front.dialog.ZSetHashInsertDialog;
import com.sk.redis.desktop.manager.front.filter.DoubleOnlyFilter;
import com.sk.redis.desktop.manager.front.panel.ShowPanel;
import com.sk.redis.desktop.manager.info.ShowInfo;
import com.sk.redis.desktop.manager.tool.RedisTool;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.text.AbstractDocument;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import static javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS;
public class ZSetPanel extends TemplatePanel implements ZSetHashInsert {
//数据表格
private JTable table;
//搜索框
private JTextField search;
private JComboBox<String> comboBox2;
//显示的面板1(此处显示score值)
private JTextPane textPane1;
//显示的面板1(此处显示value值)
private JTextPane textPane2;
//列头
private final String[] columnNames = {"row", "value", "score"};
private String score = null;
private String value = null;
private String[][] currData;
private String comBoxSelect = "Text";
private JButton deleteBtn;
private JButton insertBtn;
public ZSetPanel(ShowPanel showPanel) {
super(showPanel, true);
initTopPanel();
initCenterPanel();
initBottomPanel();
initListener();
}
@Override
void initCenterPanel() {
JSplitPane centerPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
centerPanel.setDividerLocation(130);
centerPanel.setDividerSize(5);
Box centerTopBox = Box.createHorizontalBox();
table = new JTable();
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JTableHeader tableHeader = table.getTableHeader();
Font font = new Font("微软雅黑", Font.PLAIN, 16);
tableHeader.setFont(font);
tableHeader.setReorderingAllowed(false);
table.setFont(font);
table.setAutoResizeMode(AUTO_RESIZE_ALL_COLUMNS);
JScrollPane tableScroll = new JScrollPane(table);
Box funcBox = Box.createVerticalBox();
insertBtn = new JButton("插入行");
insertBtn.setBackground(Color.CYAN);
insertBtn.setBorder(BorderFactory.createEmptyBorder(5, 64, 5, 64));
insertBtn.setIcon(Main.ICON.getIcon("add-line"));
insertBtn.setFocusable(false);
setFontSize(insertBtn, 16);
deleteBtn = new JButton("删除行");
deleteBtn.setBackground(Color.PINK);
deleteBtn.setBorder(BorderFactory.createEmptyBorder(5, 64, 5, 64));
deleteBtn.setIcon(Main.ICON.getIcon("delete-line"));
deleteBtn.setFocusable(false);
setFontSize(deleteBtn, 16);
search = new JTextField();
setFontSize(search, 16);
JPanel panel = new JPanel(new BorderLayout());
panel.add(search, BorderLayout.CENTER);
panel.setMaximumSize(new Dimension(400, search.getPreferredSize().height));
panel.setBackground(Color.BLACK);
funcBox.add(insertBtn);
funcBox.add(deleteBtn);
funcBox.add(panel);
funcBox.add(Box.createVerticalGlue());
centerTopBox.add(tableScroll);
centerTopBox.add(funcBox);
centerPanel.add(centerTopBox);
JSplitPane upDown = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
Box centerCenterBox1 = Box.createVerticalBox();
Box centerCenterLabelBox1 = Box.createHorizontalBox();
JLabel scoreLabel = new JLabel("Score: " + '\u2193');
setFontSize(scoreLabel, 16);
centerCenterLabelBox1.add(scoreLabel);
centerCenterLabelBox1.add(Box.createHorizontalGlue());
textPane1 = new JTextPane();
AbstractDocument document = (AbstractDocument) textPane1.getDocument();
document.setDocumentFilter(new DoubleOnlyFilter());
setFontSize(textPane1, 16);
JScrollPane textScroll1 = new JScrollPane(textPane1);
textScroll1.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
centerCenterBox1.add(centerCenterLabelBox1);
centerCenterBox1.add(textScroll1);
Box centerCenterBox2 = Box.createVerticalBox();
Box centerCenterLabelBox2 = Box.createHorizontalBox();
JLabel valueLabel2 = new JLabel("Value: " + '\u2193');
setFontSize(valueLabel2, 16);
JLabel viewAsLabel2 = new JLabel("View as: ");
setFontSize(viewAsLabel2, 16);
comboBox2 = new JComboBox<String>(new String[]{"Text", "JSON"});
setFontSize(comboBox2, 16);
centerCenterLabelBox2.add(valueLabel2);
centerCenterLabelBox2.add(Box.createHorizontalGlue());
centerCenterLabelBox2.add(viewAsLabel2);
centerCenterLabelBox2.add(comboBox2);
textPane2 = new JTextPane();
setFontSize(textPane2, 16);
JScrollPane textScroll2 = new JScrollPane(textPane2);
textScroll2.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
centerCenterBox2.add(centerCenterLabelBox2);
centerCenterBox2.add(textScroll2);
upDown.add(centerCenterBox1);
upDown.add(centerCenterBox2);
upDown.setDividerSize(5);
upDown.setDividerLocation(150);
centerPanel.add(upDown);
add(centerPanel, BorderLayout.CENTER);
}
@Override
void initListener() {
comboBox2.addActionListener(e -> {
comBoxSelect = (String) comboBox2.getSelectedItem();
setTextOrJson();
});
table.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
score = table.getValueAt(selectedRow, 2).toString();
value = table.getValueAt(selectedRow, 1).toString();
setTextOrJson();
setUseState();
}
}
});
search.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
String text = search.getText().trim();
if (!text.equals("")) {
addOrUpdateTable(searchData(text));
}
}
@Override
public void removeUpdate(DocumentEvent e) {
String text = search.getText().trim();
if (text.equals("")) {
reloadTable();
} else {
addOrUpdateTable(searchData(text));
}
}
@Override
public void changedUpdate(DocumentEvent e) {
}
});
insertBtn.addActionListener(e -> {
new ZSetHashInsertDialog(showPanel.getMainPanel().getMain(), this);
});
deleteBtn.addActionListener(e -> {
deleteLine();
});
save.addActionListener(e -> {
int row = table.getSelectedRow();
if (row != -1) {
try {
String newValue = textPane2.getText();
double newScore = Double.parseDouble(textPane1.getText());
RedisTool.updateZSet(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), value, newScore, newValue);
JOptionPane.showMessageDialog(showPanel.getMainPanel(), "保存成功");
reloadTable();
selectRow(newValue);
} catch (KeyNotExitsException ex) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), ex.getMessage());
clearNode();
}
}
});
}
@Override
void clearTextPanel() {
textPane1.setText("");
textPane2.setText("");
value = null;
score = null;
}
@Override
void setUseState() {
textPane1.setEnabled(true);
textPane2.setEnabled(true);
}
@Override
void setNoUseState() {
textPane1.setEnabled(false);
textPane2.setEnabled(false);
}
@Override
public void showData(ShowInfo showInfo) {
super.showInfo = showInfo;
super.setKeyType(showInfo.getType());
super.setKeyName(showInfo.getKeyName());
super.setTTl(String.valueOf(showInfo.getTtl()));
reloadTable();
super.setSize(String.valueOf(currData.length));
}
void reloadTable() {
try {
currData = RedisTool.getZSetValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName());
setSize(String.valueOf(currData.length));
addOrUpdateTable(currData);
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
void addOrUpdateTable(String[][] data) {
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table.setModel(model);
clearTextPanel();
setNoUseState();
SwingUtilities.invokeLater(() -> {
table.updateUI();
});
}
String[][] searchData(String val) {
List<String[]> data = new ArrayList<>();
for (String[] currDatum : currData) {
if (currDatum[1].contains(val)) {
data.add(currDatum);
}
}
return data.toArray(new String[0][]);
}
void setTextOrJson() {
if (value == null || score == null) {
return;
}
textPane1.setText(score);
if (comBoxSelect.equals("Text")) {
textPane2.setText(value);
} else {
String s = jsonFormat(value);
if (s != null) {
textPane2.setText(s);
} else {
textPane2.setText(value);
}
}
}
public void selectRow(String value) {
for (int i = 0; i < currData.length; i++) {
if (currData[i][1].equals(value)) {
table.setRowSelectionInterval(i, i);
break;
}
}
}
@Override
public void insertLine(String scoreOrKey, String value) throws KeyNotExitsException, HashKeyExitsException {
RedisTool.addZSet(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), Double.parseDouble(scoreOrKey), value);
reloadTable();
selectRow(value);
}
private void deleteLine() {
int selectedRow = table.getSelectedRow();
if (selectedRow != -1) {
int i = JOptionPane.showConfirmDialog(showPanel.getMainPanel(), "确认删除【" + ExceptionMessage.getMessage(value) + "】吗?", "", 2);
if (i == 0) {
try {
RedisTool.delZSetValue(showInfo.getRedis(), showInfo.getDbIndex(), showInfo.getKeyName(), value);
reloadTable();
} catch (KeyNotExitsException e) {
JOptionPane.showMessageDialog(showPanel.getMainPanel(), e.getMessage());
clearNode();
}
}
}
}
}
Main 类
package com.sk.redis.desktop.manager.front;
import com.sk.redis.desktop.manager.core.MyIcon;
import com.sk.redis.desktop.manager.front.panel.MainPanel;
import com.sk.redis.desktop.manager.front.panel.MenuPanel;
import com.sk.redis.desktop.manager.tool.ResourceTool;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.InputStream;
/**
* 主窗口
* 包含菜单面板 和 主面板
*/
public class Main extends JFrame implements WindowListener {
//icon图标资源对象
public final static MyIcon ICON;
//主窗口菜单面板
private MenuPanel menuPanel;
//主面板
private MainPanel mainPanel;
//提前将icon图标对象持久化为文件,写入了resource目录下icon文件
//目的是是为了提高效率单个加载费时1200毫秒,提前持久化好,反编译只需要30毫秒
static {
InputStream resourceAsStream = ResourceTool.RESOURCE.getResourceAsStream("icon/icon.dat");
ICON = (MyIcon) ResourceTool.loadObject(resourceAsStream);
}
public Main() {
//使用Border布局管理器,实现可以根据用户拉伸窗口自动调节子组件的宽高比。
setLayout(new BorderLayout());
//获取屏幕的尺寸
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
//屏幕尺寸宽高的0.7倍为窗口基础大小,解决不桶电脑分辨率呈现出的不一样的问题
int myWidth = (int) (screenSize.getWidth() * 0.7);
int myHeight = (int) (screenSize.getHeight() * 0.7);
//设置窗口关闭规则为关闭窗口即结束程序。
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//设置窗口位置为屏幕的水平垂直居中,位置算法为(屏幕的宽(高)-窗口的宽(高)/2)
setBounds(((int) screenSize.getWidth() - myWidth) / 2, ((int) screenSize.getHeight() - myHeight) / 2, myWidth, myHeight);
//初始化组件
initComponent();
//设置窗口左上角图标
setIconImage(ICON.getIcon("main").getImage());
//设置窗口左上角标题
setTitle("Redis Desktop Manager");
//设置面板的背景颜色
setBackground(Color.WHITE);
addWindowListener(this);
//设置容器为可见
setVisible(true);
}
//初始化组件
void initComponent() {
menuPanel = new MenuPanel(this);
//将组件设置为Border布局管理器的北面的位置(上面)
//BorderLayout的特性分为5个面板分别为东南西北和中间,中间的位置会自动填充剩余位置。
add(menuPanel, BorderLayout.NORTH);
mainPanel = new MainPanel(this);
//将组件设置为Border布局管理器的中心的位置(中间)
add(mainPanel, BorderLayout.CENTER);
}
//获取菜单面板
public MenuPanel getMenuPanel() {
return menuPanel;
}
//获取主面板
public MainPanel getMainPanel() {
return mainPanel;
}
@Override
public void windowOpened(WindowEvent e) {
}
//窗口关闭时监听
@Override
public void windowClosing(WindowEvent e) {
Runtime.getRuntime().gc();
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
}
info包
KeyInfo 类
package com.sk.redis.desktop.manager.info;
public class KeyInfo {
private String keyName;
private String type;
private String scoreOrKey;
private String value;
public KeyInfo(String keyName, String type, String scoreOrKey, String value) {
this.keyName = keyName;
this.type = type;
this.scoreOrKey = scoreOrKey;
this.value = value;
}
public String getKeyName() {
return keyName;
}
public String getType() {
return type;
}
public String getScoreOrKey() {
return scoreOrKey;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return "KeyInfo{" +
"keyName='" + keyName + '\'' +
", type='" + type + '\'' +
", scoreOrKey='" + scoreOrKey + '\'' +
", value='" + value + '\'' +
'}';
}
}
ShowInfo 类
package com.sk.redis.desktop.manager.info;
import com.sk.redis.desktop.manager.core.DataBase;
import com.sk.redis.desktop.manager.core.Redis;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import com.sk.redis.desktop.manager.tool.RedisTool;
import javax.swing.tree.DefaultMutableTreeNode;
import java.util.Objects;
//展示信息类
public class ShowInfo {
//Redis对象
private Redis redis;
//数据库节点
private DefaultMutableTreeNode dataBaseNode;
//key节点
private DefaultMutableTreeNode keyNode;
//数据库索引
private Integer dbIndex;
//key的名字
private String keyName;
//key的类型
private String type;
//ttl
private Long ttl;
public ShowInfo(Redis redis, DefaultMutableTreeNode dataBaseNode, DefaultMutableTreeNode keyNode) throws KeyNotExitsException {
this.redis = redis;
this.dataBaseNode = dataBaseNode;
this.keyNode = keyNode;
this.dbIndex = DataBase.getNodeTitleIndex(dataBaseNode.toString());
this.keyName = keyNode.toString();
this.type = RedisTool.getKeyType(redis, this.dbIndex, this.keyName);
this.ttl = RedisTool.getKeyTTL(redis, this.dbIndex, this.keyName);
}
public Redis getRedis() {
return redis;
}
public DefaultMutableTreeNode getDataBaseNode() {
return dataBaseNode;
}
public DefaultMutableTreeNode getKeyNode() {
return keyNode;
}
public Integer getDbIndex() {
return dbIndex;
}
public String getKeyName() {
return keyName;
}
public String getType() {
return type;
}
public Long getTtl() {
return ttl;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ShowInfo showInfo = (ShowInfo) o;
return Objects.equals(redis, showInfo.redis) && Objects.equals(dataBaseNode, showInfo.dataBaseNode) && Objects.equals(keyNode, showInfo.keyNode) && Objects.equals(dbIndex, showInfo.dbIndex) && Objects.equals(keyName, showInfo.keyName) && Objects.equals(type, showInfo.type) && Objects.equals(ttl, showInfo.ttl);
}
@Override
public int hashCode() {
return Objects.hash(redis, dataBaseNode, keyNode, dbIndex, keyName, type, ttl);
}
@Override
public String toString() {
return "ShowInfo{" +
"redis=" + redis +
", dataBaseNode=" + dataBaseNode +
", keyNode=" + keyNode +
", dbIndex=" + dbIndex +
", keyName='" + keyName + '\'' +
", type='" + type + '\'' +
", ttl=" + ttl +
'}';
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}
public void setTtl(Long ttl) {
this.ttl = ttl;
}
}
tool包
RedisTool 类
package com.sk.redis.desktop.manager.tool;
import com.sk.redis.desktop.manager.core.Redis;
import com.sk.redis.desktop.manager.exception.HashKeyExitsException;
import com.sk.redis.desktop.manager.exception.HashKeyNotExitsException;
import com.sk.redis.desktop.manager.exception.KeyExistException;
import com.sk.redis.desktop.manager.exception.KeyNotExitsException;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.resps.Tuple;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.IntStream;
public class RedisTool {
private static Jedis selectDb(Redis redis, Integer dbName) {
Jedis jedis = redis.getJedis();
jedis.select(dbName);
return jedis;
}
public static String getKeyType(Redis redis, Integer dbName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(key)) {
throw new KeyNotExitsException(key);
}
return jedis.type(key).toUpperCase();
}
public static Long getKeyTTL(Redis redis, Integer dbName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(key)) {
throw new KeyNotExitsException(key);
}
return jedis.ttl(key);
}
public static String getStringValue(Redis redis, Integer dbName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(key)) {
throw new KeyNotExitsException(key);
}
return jedis.get(key);
}
public static String[][] getListValue(Redis redis, Integer dbName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(key)) {
throw new KeyNotExitsException(key);
}
List<String> list = jedis.lrange(key, 0, -1);
String[][] res = new String[list.size()][2];
for (int i = 1; i <= list.size(); i++) {
res[i - 1] = new String[]{i + "", list.get(i - 1)};
}
return res;
}
public static String[][] getSetValue(Redis redis, Integer dbName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(key)) {
throw new KeyNotExitsException(key);
}
Set<String> set = jedis.smembers(key);
String[][] res = new String[set.size()][2];
int i = 1;
for (String s : set) {
res[i - 1] = new String[]{i + "", s};
i++;
}
return res;
}
public static String[][] getZSetValue(Redis redis, Integer dbName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(key)) {
throw new KeyNotExitsException(key);
}
List<Tuple> tuples = jedis.zrangeWithScores(key, 0, -1);
String[][] res = new String[tuples.size()][3];
for (int i = 1; i <= tuples.size(); i++) {
res[i - 1] = new String[]{i + "", tuples.get(i - 1).getElement(), tuples.get(i - 1).getScore() + ""};
}
return res;
}
public static String[][] getHashValue(Redis redis, Integer dbName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(key)) {
throw new KeyNotExitsException(key);
}
Map<String, String> map = jedis.hgetAll(key);
String[][] res = new String[map.size()][3];
IntStream.range(0, map.size()).forEach(
i -> {
String mapKey = (String) map.keySet().toArray()[i];
String value = map.get(mapKey);
res[i] = new String[]{i + 1 + "", mapKey, value};
}
);
return res;
}
public static long keyRename(Redis redis, Integer dbName, String keyName, String newKeyName) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
return jedis.renamenx(keyName, newKeyName);
}
public static long delKey(Redis redis, Integer dbName, String keyName) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
return jedis.del(keyName);
}
public static long getDataBaseSize(Redis redis, Integer dbName) {
Jedis jedis = selectDb(redis, dbName);
return jedis.dbSize();
}
public static long setKeyTTL(Redis redis, Integer dbName, String keyName, Long time) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
return jedis.expire(keyName, time);
}
public static boolean exitsKey(Redis redis, Integer dbName, String keyName) {
Jedis jedis = selectDb(redis, dbName);
return jedis.exists(keyName);
}
public static void addStringKey(Redis redis, Integer dbName, String keyName, String value) throws KeyExistException {
Jedis jedis = selectDb(redis, dbName);
if (jedis.exists(keyName)) {
throw new KeyExistException(keyName);
}
jedis.set(keyName, value);
}
public static void updateString(Redis redis, Integer dbName, String keyName, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
jedis.set(keyName, value);
}
public static void addSetKey(Redis redis, Integer dbName, String keyName, String value) throws KeyExistException {
Jedis jedis = selectDb(redis, dbName);
if (jedis.exists(keyName)) {
throw new KeyExistException(keyName);
}
jedis.sadd(keyName, value);
}
public static void addSet(Redis redis, Integer dbName, String keyName, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
jedis.sadd(keyName, value);
}
public static void updateSet(Redis redis, Integer dbName, String keyName, String oldValue, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
delSetValue(redis, dbName, keyName, oldValue);
jedis.sadd(keyName, value);
}
public static void addListKey(Redis redis, Integer dbName, String keyName, String value) throws KeyExistException {
Jedis jedis = selectDb(redis, dbName);
if (jedis.exists(keyName)) {
throw new KeyExistException(keyName);
}
jedis.rpush(keyName, value);
}
public static void addList(Redis redis, Integer dbName, String keyName, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
jedis.rpush(keyName, value);
}
public static void updateList(Redis redis, Integer dbName, String keyName, Integer index, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
jedis.lset(keyName, index, value);
}
public static void addZSetKey(Redis redis, Integer dbName, String keyName, Double score, String value) throws KeyExistException {
Jedis jedis = selectDb(redis, dbName);
if (jedis.exists(keyName)) {
throw new KeyExistException(keyName);
}
jedis.zadd(keyName, score, value);
}
public static void addZSet(Redis redis, Integer dbName, String keyName, Double score, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
jedis.zadd(keyName, score, value);
}
public static void updateZSet(Redis redis, Integer dbName, String keyName, String oldValue, Double score, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
delZSetValue(redis, dbName, keyName, oldValue);
jedis.zadd(keyName, score, value);
}
public static void addHashKey(Redis redis, Integer dbName, String keyName, String key, String value) throws KeyExistException {
Jedis jedis = selectDb(redis, dbName);
if (jedis.exists(keyName)) {
throw new KeyExistException(keyName);
}
jedis.hset(keyName, key, value);
}
public static void addHash(Redis redis, Integer dbName, String keyName, String key, String value) throws KeyNotExitsException, HashKeyExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
if (jedis.hexists(keyName, key)) {
throw new HashKeyExitsException(key);
}
jedis.hset(keyName, key, value);
}
public static void updateHash(Redis redis, Integer dbName, String keyName, String oldKey, String key, String value) throws HashKeyNotExitsException, KeyNotExitsException, HashKeyExitsException {
Jedis jedis = selectDb(redis, dbName);
if (jedis.hexists(keyName, key)) {
throw new HashKeyExitsException(key);
}
delHashValue(redis, dbName, keyName, oldKey);
jedis.hset(keyName, key, value);
}
public static void delListValue(Redis redis, Integer dbName, String keyName, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
jedis.lrem(keyName, 1, value);
}
public static void delSetValue(Redis redis, Integer dbName, String keyName, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
jedis.srem(keyName, value);
}
public static void delZSetValue(Redis redis, Integer dbName, String keyName, String value) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
jedis.zrem(keyName, value);
}
public static void delHashValue(Redis redis, Integer dbName, String keyName, String value) throws KeyNotExitsException, HashKeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
if (!jedis.hexists(keyName, value)) {
throw new HashKeyNotExitsException(value);
}
jedis.hdel(keyName, value);
}
public static boolean hashExits(Redis redis, Integer dbName, String keyName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
return jedis.hexists(keyName, key);
}
public static void flushDb(Redis redis, Integer dbName) {
Jedis jedis = selectDb(redis, dbName);
jedis.flushDB();
}
public static void flushAll(Redis redis) {
redis.getJedis().flushAll();
}
}
ResourceTool 类
package com.sk.redis.desktop.manager.tool;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
public class ResourceTool {
public final static ClassLoader RESOURCE = ClassLoader.getSystemClassLoader();
public static ImageIcon getICon(String resourceName, Integer width, Integer height) {
InputStream is = null;
BufferedImage read = null;
ImageIcon icon = null;
try {
is = RESOURCE.getResourceAsStream(resourceName);
if (is == null) {
return null;
}
read = ImageIO.read(is);
icon = new ImageIcon(new ImageIcon(read).getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return icon;
}
public static Image getImage(String resourceName) {
InputStream is = null;
BufferedImage read = null;
Image image = null;
try {
is = RESOURCE.getResourceAsStream(resourceName);
if (is == null) {
return null;
}
read = ImageIO.read(is);
image = new ImageIcon(read).getImage();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return image;
}
public static void saveObject(Object obj, String fileName) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
oos.writeObject(obj); // 将对象序列化为字节流并写入文件中
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object loadObject(InputStream fileName) {
Object obj = null;
try (ObjectInputStream ois = new ObjectInputStream(fileName)) {
obj = ois.readObject(); // 读取文件中的字节流并反序列化为对象
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return obj;
}
}
App 类
package com.sk.redis.desktop.manager;
import com.sk.redis.desktop.manager.front.Main;
public class App {
public static void main(String[] args) {
new Main();
}
}
resource包
icon包
icon.dat(图片持久化对象)
image包
add-connection.png
add-key.png
add-line.png
cancel.png
clear.png
copy.png
database.png
delete-line.png
key.png
main.png
refresh.png
rename.png
save.png
xitsException, HashKeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
if (!jedis.hexists(keyName, value)) {
throw new HashKeyNotExitsException(value);
}
jedis.hdel(keyName, value);
}
public static boolean hashExits(Redis redis, Integer dbName, String keyName, String key) throws KeyNotExitsException {
Jedis jedis = selectDb(redis, dbName);
if (!jedis.exists(keyName)) {
throw new KeyNotExitsException(keyName);
}
return jedis.hexists(keyName, key);
}
public static void flushDb(Redis redis, Integer dbName) {
Jedis jedis = selectDb(redis, dbName);
jedis.flushDB();
}
public static void flushAll(Redis redis) {
redis.getJedis().flushAll();
}
}
#### ResourceTool 类
```java
package com.sk.redis.desktop.manager.tool;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
public class ResourceTool {
public final static ClassLoader RESOURCE = ClassLoader.getSystemClassLoader();
public static ImageIcon getICon(String resourceName, Integer width, Integer height) {
InputStream is = null;
BufferedImage read = null;
ImageIcon icon = null;
try {
is = RESOURCE.getResourceAsStream(resourceName);
if (is == null) {
return null;
}
read = ImageIO.read(is);
icon = new ImageIcon(new ImageIcon(read).getImage().getScaledInstance(width, height, Image.SCALE_SMOOTH));
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return icon;
}
public static Image getImage(String resourceName) {
InputStream is = null;
BufferedImage read = null;
Image image = null;
try {
is = RESOURCE.getResourceAsStream(resourceName);
if (is == null) {
return null;
}
read = ImageIO.read(is);
image = new ImageIcon(read).getImage();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return image;
}
public static void saveObject(Object obj, String fileName) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
oos.writeObject(obj); // 将对象序列化为字节流并写入文件中
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object loadObject(InputStream fileName) {
Object obj = null;
try (ObjectInputStream ois = new ObjectInputStream(fileName)) {
obj = ois.readObject(); // 读取文件中的字节流并反序列化为对象
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return obj;
}
}
App 类
package com.sk.redis.desktop.manager;
import com.sk.redis.desktop.manager.front.Main;
public class App {
public static void main(String[] args) {
new Main();
}
}
resource包
icon包
icon.dat(图片持久化对象)
image包
add-connection.png
add-key.png
add-line.png
cancel.png
clear.png
copy.png
database.png
delete-line.png
key.png
main.png
refresh.png
rename.png
save.png
setting.png
使用说明
找到MyIcon类
把main方法中的new File的参数改为运行项目下的resource目录下image目录的绝对路径
效果如:
然后把MyIcon中main方法中的最后一行代码的地址改为你本地icon.dat 的文件的绝对路径。效果图如下:
修改完之后先运行MyIcon类的Main方法持久化图片资源为icon.dat文件里。
然后运行App类的Main方法就启动了