制作图形界面

This commit is contained in:
Administrator
2022-12-25 14:53:46 +08:00
parent 0797da8eb3
commit 6dd349e722
106 changed files with 13020 additions and 312 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
package org.kne.cloud.network.klalb;
public class Consts {
public static final int BLOCKSIZE=65536;
public static final long PINGTIMENS=10000000000L;
public static final int BLOCKSIZE=16384;
public static final long PINGTIMENS=2000000000L;
public static final double A = 0.125;
public static final int SO_TIMEOUT = 20000;
public static final long SN_KEEP = 60000000000L;
@@ -27,12 +27,12 @@ public class IOThreadManager {
klc.getLocaltcps().put(tc.getCuid(), tc);
AtomicBoolean AB=new AtomicBoolean(true);
try {
if (syn) {
if (syn) {
KLALBBlock sbk = new KLALBBlock();
sbk.cuid = tc.getCuid();
sbk.number = 0;
sbk.command = 2;
sbk.lservice = tc.getServiceElement().proc;
sbk.lservice = tc.getServiceElement().name;
sbk.lipport = tc.getServiceElement().ipport;
klc.submitDataBlockNoDelay(sbk);
}
@@ -165,6 +165,7 @@ public class IOThreadManager {
public void close() {
isopen = false;
//klc.get
}
public boolean isOpen() {
@@ -0,0 +1,72 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicLong;
public class InputMetre extends InputStream {
private InputStream in;
private AtomicLong total=new AtomicLong(0);
public InputMetre(InputStream inputStream) {
this.in=inputStream;
}
@Override
public int read() throws IOException {
int v=in.read();
if(v!=-1) {
total.incrementAndGet();
}
return v;
}
@Override
public int read(byte[] b) throws IOException {
int v=in.read(b);
if(v!=-1) {
total.addAndGet(v);
}
return v;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int v=in.read(b, off, len);
if(v!=-1) {
total.addAndGet(v);
}
return v;
}
@Override
public long skip(long n) throws IOException {
return in.skip(n);
}
@Override
public int available() throws IOException {
return in.available();
}
@Override
public void close() throws IOException {
in.close();
}
@Override
public synchronized void mark(int readlimit) {
in.mark(readlimit);
}
@Override
public synchronized void reset() throws IOException {
in.reset();
}
@Override
public boolean markSupported() {
return in.markSupported();
}
}
@@ -11,7 +11,7 @@ public class KLALBBlock implements Comparable<KLALBBlock>{
private static AtomicLong sng=new AtomicLong(1);
public long sn;//每个数据包的唯一编号
public UUID cuid;//用于识别数据包的stream ID号
public long cuid;//用于识别数据包的stream ID号
public long number;//数据包的编号,用于排序
public byte[]data;//数据内容
public int command;//功能标记 0=PING 1=PONG 2=SYN 3=RST
@@ -0,0 +1,64 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.BindException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import org.kne.cloud.network.mport.ServiceElement;
public class KLALBCM {
public static void main(String[] args) throws IOException {
if(args.length==0){
System.out.println("命令行参数输入服务器任意一条线路的地址:端口可以下载服务器线路列表");
System.out.println("命令行参数输入服务器名称即可启动负载均衡");
}else if(args.length==1) {
if(args[0].equals("-gui")) {
KLALBClientGUI.main(args);
}else
if(args[0].contains(":")) {
KLALBIPList.createIPList(args[0]);
}else {
File pdis=KLALBIPList.getSLdir(args[0]);
File f=new File(pdis,"iplist.json");
if(f.exists()) {
System.out.println("加载线路列表:"+f);
byte[] bytes;
try {
KLALBIPList.updateIPList(args[0]);
bytes = Files.readAllBytes(Paths.get(f.toURI()));
STJson stj=new STJson(new String(bytes));
KLALBClient kc= new KLALBClient();
kc.getTls().addAll(stj.getTunnels());
kc.connectTunnel();
List<ServiceElement> lse=stj.getServices();
for (Iterator<ServiceElement> iterator = lse.iterator(); iterator.hasNext();) {
ServiceElement serviceElement = (ServiceElement) iterator.next();
ProxyIPPortProperties pippp=new ProxyIPPortProperties(pdis, serviceElement.name, "127.0.0.1", serviceElement.ipport.getPort());
try {
kc.open(pippp.getBindPort(),serviceElement, pippp.getBindIP());
}catch(BindException e) {
System.out.println("打开端口失败:"+pippp.getBindIP()+" "+pippp.getBindPort());
e.printStackTrace();
}
}
}catch (IOException e) {
e.printStackTrace();
}
}else {
System.out.println("线路列表不存在");
}
}
}else {
}
}
}
@@ -5,6 +5,8 @@ import java.io.BufferedOutputStream;
import java.io.EOFException;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.Socket;
@@ -12,7 +14,10 @@ import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.UUID;
@@ -23,19 +28,20 @@ import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
import org.kne.cloud.network.mport.ThreadTool;
import com.google.gson.stream.JsonReader;
public class KLALBClient {
UUID suid=UUID.randomUUID();
IOThreadManager iom=new IOThreadManager();
private UUID suid=UUID.randomUUID();
private IOThreadManager iom=new IOThreadManager();
private List<Tunnel> tls=new ArrayList<>();
private TCPListener tcpl;
private ServiceElement sel;
private List<TCPListener> tcpl=new ArrayList<>();
public void open(int port) throws IOException {
tcpl=new TCPListener(port);
tcpl.setCon((s)->{
public void open(int port, ServiceElement sel,String bindip) throws IOException {
TCPListener tl=new TCPListener(port,bindip);
tl.setCon((s)->{
LocalTCPConnection tcc = null;
try {
tcc = new LocalTCPConnection(s);
@@ -51,7 +57,11 @@ public class KLALBClient {
}
}
});
tcpl.open();
tl.open();
tcpl.add(tl);
System.out.println(sel.name+"映射已启动 端口:"+port+" 绑定地址:"+bindip);
}
public void connectTunnel() {
for (int i = 0; i < tls.size(); i++) {
Tunnel tll=tls.get(i);
ThreadTool.makeVThreadIfSupport("隧道监视线程", ()->{
@@ -75,8 +85,10 @@ public class KLALBClient {
}
re=0;
System.out.println(tll+":连接成功");
tll.setState(true);
iom.handleRemote(tc);
System.out.println(tll+":连接断开");
tll.setState(false);
} catch (UnknownHostException e) {
e.printStackTrace();
}catch(ConnectException|SocketTimeoutException e) {
@@ -84,7 +96,7 @@ public class KLALBClient {
} catch (IOException e) {
e.printStackTrace();
}finally {
if(tc!=null)
if(tc!=null)
tc.close();
}
try {
@@ -105,92 +117,16 @@ public class KLALBClient {
public List<ServiceElement> getServices() {
return services;
}
public void searchTunnels(String ipport) throws IOException {
IPPort u=new IPPort(ipport);
TCPConnection tcpc=null;
try {
tcpc=new RemoteTCPConnection(null, new Socket(u.getIp(),u.getPort()));
tcpc.getDout().writeShort(59649);
tcpc.getDout().write(0);
tcpc.getDout().flush();
int s=tcpc.getDin().readInt();
System.out.println("服务列表:");
for (int i = 0; i < s; i++) {
String str=tcpc.getDin().readUTF();
System.out.println(str);
services.add(new ServiceElement(str));
}
int s2=tcpc.getDin().readInt();
System.out.println("隧道列表:");
for (int i = 0; i < s2; i++) {
String str=tcpc.getDin().readUTF();
System.out.println(str);
tls.add(Tunnel.newTunnel(str));
}
}finally {
if(tcpc!=null) {
tcpc.close();
}
public void close() {
iom.close();
for (Iterator<TCPListener> iterator = tcpl.iterator(); iterator.hasNext();) {
TCPListener tl = (TCPListener) iterator.next();
tl.close();
}
}
public ServiceElement getSel() {
return sel;
}
public void setSel(ServiceElement sel) {
this.sel = sel;
}
public static void main(String[] args) throws IOException {
Scanner scn=new Scanner(System.in);
KLALBClient kc=new KLALBClient();
/*File f=new File("klalbc.ini");
if(!f.exists()) {
f.createNewFile();
return;
}
Scanner scn=new scan*/
System.out.println("请输入服务器任意一条线路的地址:");
kc.searchTunnels(scn.next());//"153.36.240.12:65529"
System.out.println("你想要连接哪个服务?请输入序号:");
kc.setSel(kc.getServices().get(scn.nextInt()));
System.out.println("请输入你要映射的本地端口:");
kc.open(scn.nextInt());
System.out.println("服务已开启");
while(true) {
String s=scn.next();
switch(s) {
case "states":
Tunnel.states();
break;
}
}
}
//Tunnel t= new Tunnel("Test1", "127.0.0.1", 4569);
/*Tunnel t= new Tunnel("Test1", "cn-hz-bgp-1.openfrp.top", 65529);
tls.add(t);
Tunnel t2=new Tunnel("Test2","cn-bj-bgp-3.openfrp.top",65529);
tls.add(t2);
Tunnel t3=new Tunnel("Test3","180.76.147.250",65529);
tls.add(t3);
Tunnel t4=new Tunnel("Test4","cn-sx-xa-bgp-1.openfrp.top",65529);
tls.add(t4);
*/
/* List<Tunnel> tls=kc.getTls();
Tunnel t5=new Tunnel("Test5","la.afrps.cn",49966);
tls.add(t5);
Tunnel t6=new Tunnel("Test6","sg.afrps.cn",49966);
tls.add(t6);
Tunnel t7=new Tunnel("Test7","ch.afrps.cn",49966);
tls.add(t7);
Tunnel t8=new Tunnel("Test8","sj.afrps.cn",49966);
tls.add(t8);
Tunnel t9=new Tunnel("Test9","frp.104300.xyz",49965);
tls.add(t9);
Tunnel t11=new Tunnel("Test11","153.36.240.12",65529);
tls.add(t11);
Tunnel t12=new Tunnel("Test12","frp.freefrps.com",49965);
tls.add(t12);*/
}
@@ -1,22 +1,293 @@
package org.kne.cloud.network.klalb;
import java.awt.Color;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.BindException;
import java.net.ConnectException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.plaf.TabbedPaneUI;
import javax.swing.plaf.metal.MetalTabbedPaneUI;
import org.kne.cloud.network.mport.ServiceElement;
import org.kne.cloud.network.mport.ThreadTool;
import org.kne.ui.KTabUI;
import org.kne.ui.XFrame;
import org.kne.ui.YScrollPane;
import org.knemcl.ui.ProcessingFrame;
import org.knemcl.ui.UIEnv;
public class KLALBClientGUI extends XFrame{
import java.awt.AWTException;
import java.awt.BorderLayout;
import javax.swing.JTabbedPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.ActionEvent;
public class KLALBClientGUI extends XFrame {
private JComboBox comboBox;
BufferedImage bi;
private Thread t;
public KLALBClientGUI() {
setResizable(false);
setTitleColor(new Color(0,0,255,128));
getContentPane().setBackground(new Color(128,128,255,128));
setTitleColor(UIEnv.getDefaultTitleColor());
try {
bi = ImageIO.read(KLALBClientGUI.class.getResourceAsStream("/assets/KNEL.png"));
} catch (IOException e) {
e.printStackTrace();
}
setIconImage(bi);
getTitlelabel().setForeground(Color.WHITE);
getContentPane().setBackground(UIEnv.getDefaultTitleColor());
comboBox = new JComboBox();
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
}
});
reloadCB();
YScrollPane ysp = new YScrollPane(580);
ysp.setOpaque(false);
getContentPane().add(ysp);
JPanel wv = ysp.getView();
wv.addComponentListener(new ComponentListener() {
@Override
public void componentShown(ComponentEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void componentResized(ComponentEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void componentMoved(ComponentEvent e) {
repaint();
}
@Override
public void componentHidden(ComponentEvent e) {
// TODO 自动生成的方法存根
}
});
JPanel panel_1 = new JPanel();
panel_1.setOpaque(false);
getContentPane().add(panel_1, BorderLayout.NORTH);
panel_1.setLayout(new BorderLayout(0, 0));
panel_1.add(comboBox, BorderLayout.CENTER);
JButton btnNewButton = new JButton("\u6DFB\u52A0");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String s = JOptionPane.showInputDialog(KLALBClientGUI.this, "输入一条线路的地址");
if (s != null) {
if (s.equals("")) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, "输入不能为空", "错误", JOptionPane.WARNING_MESSAGE);
} else {
ProcessingFrame psf = new ProcessingFrame("正在下载线路列表");
psf.setIconImage(bi);
psf.getProgressBar().setIndeterminate(true);
psf.setVisible(true);
ThreadTool.makeVThreadIfSupport("线路列表获取", () -> {
try {
KLALBIPList.createIPList(s);
reloadCB();
} catch (Exception e1) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, e1.toString(), "错误",
JOptionPane.ERROR_MESSAGE);
e1.printStackTrace();
} finally {
psf.setVisible(false);
}
}).start();
}
}
}
});
panel_1.add(btnNewButton, BorderLayout.WEST);
JButton btnNewButton_1 = new JButton("\u542F\u52A8");
btnNewButton_1.setForeground(Color.GREEN);
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent edf) {
if(t!=null) {
t.interrupt();
t=null;
return;
}
t=ThreadTool.makeVThreadIfSupport("客户端主线程", () -> {
btnNewButton_1.setEnabled(false);
comboBox.setEnabled(false);
String s = (String) comboBox.getSelectedItem();
File pdis = KLALBIPList.getSLdir(s);
File f = new File(pdis, "iplist.json");
if (f.exists()) {
System.out.println("加载线路列表:" + f);
byte[] bytes;KLALBClient kc=null;
try {
KLALBIPList.updateIPList(s);
bytes = Files.readAllBytes(Paths.get(f.toURI()));
STJson stj = new STJson(new String(bytes));
kc = new KLALBClient();
kc.getTls().addAll(stj.getTunnels());
List<Tunnel>lt=kc.getTls();
for (Iterator<Tunnel> iterator = lt.iterator(); iterator.hasNext();) {
Tunnel tunnel = (Tunnel) iterator.next();
TPanel tp=new TPanel(tunnel);
tp.getTname().setForeground(Color.RED);
wv.add(tp);
tunnel.setTlr(new TListener() {
@Override
public void setDelay(long delay) {
tp.setDelay(delay);
repaint();
}
@Override
public void setState(boolean state) {
if(state) {
tp.getTname().setForeground(Color.GREEN);
}else {
tp.getTname().setForeground(Color.RED);
}
repaint();
}
});
}
ysp.updateUI();
ysp.repaint();
repaint();
kc.connectTunnel();
List<ServiceElement> lse = stj.getServices();
for (Iterator<ServiceElement> iterator = lse.iterator(); iterator.hasNext();) {
ServiceElement serviceElement = (ServiceElement) iterator.next();
ProxyIPPortProperties pippp = new ProxyIPPortProperties(pdis, serviceElement.name,
"127.0.0.1", serviceElement.ipport.getPort());
try {
kc.open(pippp.getBindPort(), serviceElement, pippp.getBindIP());
} catch (BindException e) {
System.out.println("打开端口失败:" + pippp.getBindIP() + " " + pippp.getBindPort());
e.printStackTrace();
}
}
btnNewButton_1.setForeground(Color.RED);
btnNewButton_1.setText("停止");
btnNewButton_1.setEnabled(true);
while(true) {
Thread.sleep(999);
}
} catch (ConnectException e) {
JOptionPane.showMessageDialog(KLALBClientGUI.this, e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
}finally {
if(kc!=null) {
kc.close();
}
}
} else {
System.out.println("线路列表不存在");
}
btnNewButton_1.setForeground(Color.GREEN);
btnNewButton_1.setText("启动");
btnNewButton_1.setEnabled(true);
comboBox.setEnabled(true);
});t.start();
}
});
panel_1.add(btnNewButton_1, BorderLayout.EAST);
setTitle("KNE云网络负载均衡客户端");
setSize(600,370);
setSize(600, 370);
setLocationRelativeTo(null);
setVisible(true);
if (SystemTray.isSupported()) {
SystemTray st = SystemTray.getSystemTray();
TrayIcon ti = new TrayIcon(bi);
ti.setImageAutoSize(true);
PopupMenu jpm = new PopupMenu();
MenuItem mi = new MenuItem("退出");
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
jpm.add(mi);
ti.setPopupMenu(jpm);
try {
st.add(ti);
} catch (AWTException e1) {
e1.printStackTrace();
}
ti.addActionListener((x) -> {
setVisible(true);
});
}
repaint();
}
private void reloadCB() {
comboBox.removeAllItems();
File f = new File("KLALB");
f.mkdirs();
File[] fs = f.listFiles();
for (int i = 0; i < fs.length; i++) {
if (new File(fs[i], "iplist.json").exists()) {
comboBox.addItem(fs[i].getName());
}
}
}
public static void main(String[] args) {
new KLALBClientGUI();
}
}
}
@@ -35,10 +35,9 @@ import java.util.function.Predicate;
import org.kne.cloud.network.mport.ThreadTool;
public class KLALBCore {
private static final UUID ZERO_UUID=new UUID(0,0);
private volatile int cacheblocks;
private Map<UUID,LocalTCPConnection> localtcps = new ConcurrentHashMap<>();
private Map<Long,LocalTCPConnection> localtcps = new ConcurrentHashMap<>();
private List<RemoteTCPConnection> remotetcps = new Vector<>();
private Predicate<KLALBBlock>acceptSYN;
@@ -82,7 +81,7 @@ public class KLALBCore {
this.acceptSYN = acceptSYN;
}
public Map<UUID, LocalTCPConnection> getLocaltcps() {
public Map<Long, LocalTCPConnection> getLocaltcps() {
return localtcps;
}
@@ -99,7 +98,7 @@ public class KLALBCore {
if(tc.checkPingTime()) {
KLALBBlock pdb=new KLALBBlock();
pdb.sn=0;
pdb.cuid=ZERO_UUID;
pdb.cuid=0;
pdb.number=0;
pdb.command=0;
pdb.pingtime=System.nanoTime();
@@ -141,13 +140,13 @@ public class KLALBCore {
}
}
}
}
if(brc.cuid.equals(ZERO_UUID)) {
}
if(brc.cuid==0) {
if(brc.number==0) {
if(brc.command==0) {
KLALBBlock pdb=new KLALBBlock();
pdb.sn=0;
pdb.cuid=ZERO_UUID;
pdb.cuid=0;
pdb.number=0;
pdb.command=1;
pdb.pingtime=brc.pingtime;
@@ -244,9 +243,9 @@ public class KLALBCore {
while (!tc.getOutputcache().isEmpty()&&(tc.getOutputcount()-tc.getOutputcache().get(0).number>cacheblocks)) {
Thread.sleep(1);
}
submitDataBlock(ks);
ks.sendtime=System.nanoTime();
tc.getOutputcache().add(ks);
submitDataBlock(ks);
if(tc.getPeerCacheUsed()>cacheblocks) {
while(tc.getPeerCacheUsed()>cacheblocks) {
Thread.sleep(1);
@@ -263,7 +262,7 @@ public class KLALBCore {
for (int i = 0; i < l.size(); i++) {
KLALBBlock block=l.get(i);
long timex = (System.nanoTime() - block.sendtime) / 1000000;
if (timex > 200*(1<<Math.min(8,block.resend))+1000*i) {
if (timex > 100*(1<<Math.min(8,block.resend))+1000*i) {
submitDataBlock(block);
block.sendtime = System.nanoTime();
block.resend++;
@@ -0,0 +1,65 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ConnectException;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import org.kne.cloud.network.mport.IPPort;
public class KLALBIPList {
public static String searchTunnels(String ipport) throws IOException {
IPPort u=new IPPort(ipport);
TCPConnection tcpc=null;
try {
tcpc=new RemoteTCPConnection(null, new Socket(u.getIp(),u.getPort()));
tcpc.getDout().writeShort(59649);
tcpc.getDout().write(0);
tcpc.getDout().flush();
String json=tcpc.getDin().readUTF();
return json;
}finally {
if(tcpc!=null) {
tcpc.close();
}
}
}
public static File getSLdir(String name) {
File f=new File("./KLALB/"+name);
f.getParentFile().mkdirs();
return f;
}
public static void createIPList(String address) throws IOException {
String json=KLALBIPList.searchTunnels(address);
STJson stj=new STJson(json);
File f=new File(getSLdir(stj.getName()),"iplist.json");
System.out.println("线路列表已保存到:"+f);
f.getParentFile().mkdirs();
f.createNewFile();
PrintStream ps=new PrintStream(f);
ps.print(json);
ps.close();
}
public static void updateIPList(String name) throws IOException {
File f=getSLdir(name);
File j=new File(f, "iplist.json");
byte[]bytes = Files.readAllBytes(Paths.get(j.toURI()));
STJson stj = new STJson(new String(bytes));
List<Tunnel> l=stj.getTunnels();
for (Iterator iterator = l.iterator(); iterator.hasNext();) {
Tunnel tunnel = (Tunnel) iterator.next();
try{
createIPList(tunnel.getIpport().toString());
return;
}catch(IOException e) {
e.printStackTrace();
}
}
throw new ConnectException("搜索地址失败");
}
}
+22 -87
View File
@@ -2,117 +2,52 @@ package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Scanner;
import java.util.function.Supplier;
import org.kne.cloud.network.mport.ServiceElement;
public class KLALBSM {
public static Map<String, ServiceElement> services=new HashMap<String, ServiceElement>();
public static List<Tunnel> tunnels=new ArrayList<Tunnel>();
public static void main(String[] args) throws IOException {
File f=new File("klalbs.ini");
if(!f.exists()) {
f.createNewFile();
ept();
return;
}
if(f.length()<=0) {
ept();
return;
}
Scanner scn=new Scanner(f);
int remp=scn.nextInt();
System.out.println("KNE云负载均衡调度软件服务端V0.1");
ServerPropties sp=new ServerPropties();
int remp=sp.getPort();
System.out.println("开放端口:"+remp);
int x=0;
System.out.println("服务列表:");
while(scn.hasNext() ) {
String s=scn.next();
if(">".equals(s)) {
x++;
System.out.println("隧道列表:");
continue;
}
switch(x) {
case 0:
ServiceElement se=new ServiceElement(s);
System.out.println(se);
services.put(se.proc,se);
break;
case 1:
Tunnel t=Tunnel.newTunnel(s);
System.out.println(t);
tunnels.add(t);
break;
}
new KLALBServer(remp,new Supplier<String>() {
}
scn.close();
new KLALBServer(remp,services,tunnels);
@Override
public String get() {
String sj="";
byte[] bytes;
try {
bytes = Files.readAllBytes(Paths.get("klalbs.json"));
sj = new String(bytes);
}catch (IOException e) {
e.printStackTrace();
}
return sj;
}
});
System.out.println("提示:运行时输入reload可以重新加载配置文件,已经建立的TCP连接不受影响(暂不支持修改开放端口)");
Scanner scn2=new Scanner(System.in);
while(true) {
String command=scn2.next();
switch(command) {
case "reload":
synchronized (services) {
synchronized(tunnels) {
scn=new Scanner(f);
services.clear();
tunnels.clear();
remp=scn.nextInt();
x=0;
System.out.println("服务列表:");
while(scn.hasNext() ) {
String s=scn.next();
if(">".equals(s)) {
x++;
System.out.println("隧道列表:");
continue;
}
switch(x) {
case 0:
ServiceElement se=new ServiceElement(s);
System.out.println(se);
services.put(se.proc,se);
break;
case 1:
Tunnel t=Tunnel.newTunnel(s);
System.out.println(t);
tunnels.add(t);
break;
}
}
scn.close();
}
}
break;
}
}
}
private static void ept() {
System.out.println("请填写配置文件后再启动程序!");
System.out.println("格式:");
System.out.println("开放端口");
System.out.println("服务协议1$服务地址1$服务端口1");
System.out.println("服务协议2$服务地址2$服务端口2");
System.out.println("......");
System.out.println("服务协议n$服务地址n$服务端口n");
System.out.println(">");
System.out.println("隧道名称1$隧道地址1$隧道端口1");
System.out.println("隧道名称2$隧道地址2$隧道端口2");
System.out.println("......");
System.out.println("隧道名称n$隧道地址n$隧道端口n");
System.out.println("");
System.out.println("按照顺序从上向下匹配,若都不是则匹配最后一个");
}
}
@@ -13,6 +13,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.WeakHashMap;
import java.util.function.Supplier;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
@@ -21,12 +22,12 @@ import org.kne.cloud.network.mport.ThreadTool;
public class KLALBServer {
WeakHashMap<UUID, IOThreadManager> whm=new WeakHashMap<>();
public KLALBServer(int port, Map<String,ServiceElement> services,List<Tunnel> tunnels) throws IOException {
public KLALBServer(int port,Supplier<String> gjso) throws IOException {
TCPListener tcpl=new TCPListener(port);
tcpl.setCon((s)->{
RemoteTCPConnection tcc=null;
try {
//s.setSoTimeout(10000);
//s.setSoTimeout(10000);
tcc=new RemoteTCPConnection(null,s);
DataInputStream din=tcc.getDin();
int val=din.readShort()&0xffff;
@@ -35,21 +36,8 @@ public class KLALBServer {
}
int x=din.read();
if(x==0) {
synchronized (services) {
tcc.getDout().writeInt(services.size());
Collection<ServiceElement> cll=services.values();
for (Iterator<ServiceElement> iterator = cll.iterator(); iterator.hasNext();) {
ServiceElement tunnel = iterator.next();
tcc.getDout().writeUTF(tunnel.toString());
}
}
synchronized (tunnels) {
int counts=tunnels.size();
tcc.getDout().writeInt(counts);
for (int i = 0; i < counts; i++) {
tcc.getDout().writeUTF(tunnels.get(i).toString());
}
}
String sj=gjso.get();
tcc.getDout().writeUTF(sj);
tcc.getDout().flush();
return;
}
@@ -57,7 +45,7 @@ public class KLALBServer {
String name = din.readUTF();
String ip = din.readUTF();
int portx=din.readInt();
Tunnel tll=Tunnel.newTunnel(name, ip, portx);
Tunnel tll=new Tunnel(name,new IPPort( ip, portx));
tcc.setTunnel(tll);
UUID uid=new UUID(din.readLong(),din.readLong());
@@ -5,12 +5,15 @@ import java.net.Socket;
import java.util.*;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Consumer;
import org.kne.cloud.network.mport.ServiceElement;
public class LocalTCPConnection extends TCPConnection {
private UUID cuid;
private static AtomicLong sng=new AtomicLong(1);
private long cuid;
private ServiceElement serviceElement;
@@ -21,16 +24,16 @@ private volatile long inputcount = 1;
private volatile long outputcount = 1;
public LocalTCPConnection(Socket s) throws IOException {
super(s);
cuid=UUID.randomUUID();
cuid=sng.getAndIncrement();
}
public LocalTCPConnection(Socket s,UUID uid) throws IOException {
public LocalTCPConnection(Socket s,long uid) throws IOException {
super(s);
cuid=uid;
}
public UUID getCuid() {
public long getCuid() {
return cuid;
}
public void setCuid(UUID cuid) {
public void setCuid(long cuid) {
this.cuid = cuid;
}
public ServiceElement getServiceElement() {
@@ -0,0 +1,43 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.atomic.AtomicLong;
public class OutputMetre extends OutputStream {
private OutputStream out;
private AtomicLong total=new AtomicLong(0);
public OutputMetre(OutputStream outputStream) {
this.out=outputStream;
}
@Override
public void write(int b) throws IOException {
out.write(b);
total.incrementAndGet();
}
@Override
public void write(byte[] b) throws IOException {
out.write(b);
total.addAndGet(b.length);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
out.write(b, off, len);
total.addAndGet(len);
}
@Override
public void flush() throws IOException {
out.flush();
}
@Override
public void close() throws IOException {
out.close();
}
}
@@ -0,0 +1,42 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.net.InetAddress;
import java.util.Properties;
import org.kne.cloud.network.mport.ServiceElement;
public class ProxyIPPortProperties extends Properties{
public ProxyIPPortProperties(File location ,String name,String dip,int dport) throws FileNotFoundException, IOException {
File f=new File(location,name+".json");
if(!f.exists()||f.length()==0) {
f.createNewFile();
PrintStream ps=new PrintStream(f);
ps.println("bindport="+dport);
ps.println("bindip="+dip);
ps.close();
}
FileReader fr = null;
try {
fr=new FileReader(f);
load(fr);
}finally {
if(fr!=null)
fr.close();
}
}
public int getBindPort() {
return Integer.parseInt((String) get("bindport"));
}
public String getBindIP() {
return (String) get("bindip");
}
}
@@ -1,5 +1,7 @@
package org.kne.cloud.network.klalb;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
@@ -14,6 +16,12 @@ public class RemoteTCPConnection extends TCPConnection {
public RemoteTCPConnection(Tunnel t) throws UnknownHostException, IOException {
this(t, t.connectClientSocket());
}
@Override
protected void initIO() throws IOException {
dout = new DataOutputStream(new OutputMetre( connect.getOutputStream()));
din = new DataInputStream(new InputMetre(connect.getInputStream()));
}
public RemoteTCPConnection(Tunnel t, Socket s) throws UnknownHostException, IOException {
super(s);
@@ -47,8 +55,7 @@ public class RemoteTCPConnection extends TCPConnection {
public void sendBlock(KLALBBlock data) throws IOException {
dout.writeLong(data.sn);
if(data.sn!=0) {
dout.writeLong(data.cuid.getMostSignificantBits());
dout.writeLong(data.cuid.getLeastSignificantBits());
dout.writeLong(data.cuid);
}
dout.writeLong(data.number);
if (data.number > 0) {
@@ -83,9 +90,9 @@ public class RemoteTCPConnection extends TCPConnection {
KLALBBlock klb = new KLALBBlock();
klb.sn = din.readLong();
if(klb.sn!=0) {
klb.cuid = new UUID(din.readLong(), din.readLong());
klb.cuid = din.readLong();
}else {
klb.cuid=new UUID(0,0);
klb.cuid=0;
}
klb.number = din.readLong();
if (klb.number > 0) {
@@ -0,0 +1,84 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.io.StringReader;
import java.util.*;
import org.kne.cloud.network.mport.IPPort;
import org.kne.cloud.network.mport.ServiceElement;
import com.google.gson.stream.JsonReader;
public class STJson {
private String name;
private List<ServiceElement> services=new ArrayList<>();
private List<Tunnel> tunnels=new ArrayList<>();
public List<ServiceElement> getServices() {
return services;
}
public List<Tunnel> getTunnels() {
return tunnels;
}
public STJson(String json) throws IOException {
JsonReader sr = new JsonReader(new StringReader(json));
sr.beginObject();
while (sr.hasNext()) {
String n = sr.nextName();
if (n.equals("name")) {
name = sr.nextString();
} else if (n.equals("services")) {
sr.beginArray();
while (sr.hasNext()) {
sr.beginObject();
ServiceElement se=new ServiceElement();
while (sr.hasNext()) {
String n2 = sr.nextName();
if (n2.equals("name")) {
se.name=sr.nextString();
} else if (n2.equals("protocol")) {
se.protocol=sr.nextString();
} else if (n2.equals("localaddress")) {
se.ipport=new IPPort( sr.nextString());
} else{
sr.skipValue();
}
}
services .add(se);
sr.endObject();
}
sr.endArray();
} else if (n.equals("tunnels")) {
sr.beginArray();
while (sr.hasNext()) {
sr.beginObject();
Tunnel t=new Tunnel();
while (sr.hasNext()) {
String n2 = sr.nextName();
if (n2.equals("name")) {
t.setName(sr.nextString());
} else if (n2.equals("remoteaddress")) {
t.setIpport(new IPPort( sr.nextString()));
} else{
sr.skipValue();
}
}
tunnels.add(t);
sr.endObject();
}
sr.endArray();
} else {
sr.skipValue();
}
}
sr.endObject();
}
public String getName() {
return name;
}
}
@@ -0,0 +1,36 @@
package org.kne.cloud.network.klalb;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;
public class ServerPropties extends Properties {
public ServerPropties() throws IOException {
super();
load();
}
public void load() throws IOException {
File f=new File("kserver.ini");
if(!f.exists()||f.length()==0) {
f.createNewFile();
PrintStream ps=new PrintStream(f);
ps.println("port=4569");
ps.close();
}
FileReader fr = null;
try {
fr=new FileReader(f);
load(fr);
}finally {
if(fr!=null)
fr.close();
}
}
public int getPort() {
return Integer.parseInt( (String) get("port"));
}
}
@@ -15,7 +15,7 @@ public class TCPConnection {
private Socket connect;
protected Socket connect;
protected DataInputStream din;
protected DataOutputStream dout;
@@ -1,6 +1,7 @@
package org.kne.cloud.network.klalb;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.function.Consumer;
@@ -10,12 +11,13 @@ import org.kne.cloud.network.mport.ThreadTool;
public class TCPListener {
private int port;
private ServerSocket servers;
private String bind;
private volatile boolean flag=false;
private Consumer<Socket>con;
private Runnable r=new Runnable() {
@Override
public void run() {
public void run() {
while(flag){
try {
Socket soce=servers.accept();
@@ -31,10 +33,19 @@ public class TCPListener {
public TCPListener(int port) throws IOException {
this.port=port;
}
public TCPListener(int port,String bind) throws IOException {
this.port=port;
this.bind=bind;
}
public void open() throws IOException {
flag=true;
if(bind==null) {
servers=new ServerSocket(port);
}else {
servers=new ServerSocket();
servers.bind(new InetSocketAddress(bind, port));
}
new Thread(r).start();
}
public void close() {
@@ -0,0 +1,9 @@
package org.kne.cloud.network.klalb;
public interface TListener {
void setDelay(long delay);
void setState(boolean state);
}
@@ -0,0 +1,72 @@
package org.kne.cloud.network.klalb;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import java.awt.Font;
public class TPanel extends JPanel{
private JLabel tname;
private JLabel targ;
private Tunnel tunnel;
public JLabel getTname() {
return tname;
}
public JLabel getTarg() {
return targ;
}
public TPanel (Tunnel t) {
this(t.getName());
this.tunnel=t;
}
/**
* @wbp.parser.constructor
*/
public TPanel(String name) {
setOpaque(false);
setLayout(new BorderLayout(0, 0));
tname = new JLabel(name);
tname.setFont(new Font("ËÎÌå", Font.BOLD, 20));
add(tname, BorderLayout.WEST);
targ = new JLabel();
targ.setFont(new Font("ËÎÌå", Font.PLAIN, 14));
targ.setHorizontalAlignment(SwingConstants.TRAILING);
targ.setForeground(Color.YELLOW);
add(targ, BorderLayout.CENTER);
setBorder(new LineBorder(Color.BLACK));
setSize(570, 30);
setPreferredSize(getSize());
}
private long up,down,delay;
public long getUp() {
return up;
}
public void setUp(long up) {
this.up = up;
targ.setText(up+"\u2191 "+down+"\u2193 "+delay/1000000+"ms");
}
public long getDown() {
return down;
}
public void setDown(long down) {
this.down = down;
targ.setText(up+"\u2191 "+down+"\u2193 "+delay/1000000+"ms");
}
public long getDelay() {
return delay;
}
public void setDelay(long delay) {
this.delay = delay;
targ.setText(up+"\u2191 "+down+"\u2193 "+delay/1000000+"ms");
}
}
+43 -39
View File
@@ -17,74 +17,79 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.naming.spi.Resolver;
import javax.swing.JPanel;
import org.kne.cloud.network.mport.IPPort;
public class Tunnel {
public class Tunnel{
private String name;
private IPPort ipport;
private boolean state=false;
private TListener tlr;
public boolean isState() {
return state;
}
public void setState(boolean state) {
this.state = state;
if(tlr!=null) {
tlr.setState(state);
}
}
public IPPort getIpport() {
return ipport;
}
private long delay=Long.MAX_VALUE;
public TListener getTlr() {
return tlr;
}
public void setTlr(TListener tlr) {
this.tlr = tlr;
}
public long getDelay() {
return delay;
}
public void setDelay(long delay) {
this.delay = delay;
if(tlr!=null)
tlr.setDelay(delay);
}
private static Map<IPPort,Tunnel> tls=new ConcurrentHashMap<>();
private Tunnel(String name, IPPort ipport) throws UnknownHostException {
super();
this.name = name;
this.ipport=ipport;
}
public static Tunnel newTunnel(String name, IPPort ipport) throws UnknownHostException {
Tunnel tmp=tls.get(ipport);
if(tmp!=null) {
return tmp;
}
tmp=new Tunnel(name, ipport);
tls.put(ipport, tmp);
return tmp;
}
public static Tunnel newTunnel(String name, String ipport) throws UnknownHostException {
public Tunnel() {
return newTunnel(name, new IPPort(ipport));
}
public static Tunnel newTunnel(String name, String ip, int port) throws UnknownHostException {
return newTunnel(name, new IPPort(ip, port));
}
public static Tunnel newTunnel(String s) throws UnknownHostException {
String[]t=s.split("\\$");
return newTunnel(t[0], t[1]);
public Tunnel(String name, IPPort ipport) {
super();
this.name = name;
this.ipport = ipport;
}
public String getName() {
return name;
}
public String getIp() {
return ipport.getIp().getHostAddress();
return getIpport().getIp().getHostAddress();
}
public int getPort() {
return ipport.getPort();
return getIpport().getPort();
}
@Override
public String toString() {
return name+"$"+ipport;
return getName()+"$"+getIpport();
}
public Socket connectClientSocket() throws UnknownHostException, IOException {
Socket socket=new Socket();
socket.connect(ipport.getSocketAddress(), 10000);
socket.connect(getIpport().getSocketAddress(), 10000);
return socket;
}
@Override
public int hashCode() {
return Objects.hash(ipport, name);
return Objects.hash(getIpport(), getName());
}
@Override
public boolean equals(Object obj) {
@@ -95,20 +100,19 @@ public class Tunnel {
if (getClass() != obj.getClass())
return false;
Tunnel other = (Tunnel) obj;
return Objects.equals(ipport, other.ipport) && Objects.equals(name, other.name);
}
public static void states() {
Set<Entry<IPPort, Tunnel>> s=tls.entrySet();
for (Iterator iterator = s.iterator(); iterator.hasNext();) {
Entry<IPPort, Tunnel> entry = (Entry<IPPort, Tunnel>) iterator.next();
Tunnel tll=entry.getValue();
System.out.println(tll.getName()+" "+((tll.getDelay()==Long.MAX_VALUE)?"δ֪":tll.getDelay()/1000000+"ms")+" Á¬½ÓÊý"+tll.ati);
}
return Objects.equals(getIpport(), other.getIpport()) && Objects.equals(getName(), other.getName());
}
private AtomicInteger ati=new AtomicInteger(0);
public AtomicInteger getCCount() {
return ati;
}
public void setName(String name) {
this.name = name;
}
public void setIpport(IPPort ipport) {
this.ipport = ipport;
}
}
@@ -38,7 +38,7 @@ public class PortRelay {
se = ServiceElement.getbyproc(services, n);
InetSocketAddress sa=(InetSocketAddress) s.getRemoteSocketAddress();
System.out.println(sa.getAddress().getHostAddress() + ":" + port
+ "-" + se.proc + "(" + n + ")->" + se.ipport.getIp().getHostAddress() + ":" + se.ipport.getPort());
+ "-" + se.protocol + "(" + n + ")->" + se.ipport.getIp().getHostAddress() + ":" + se.ipport.getPort());
sl.connect(new InetSocketAddress(se.ipport.getIp().getHostAddress(), se.ipport.getPort()));
final DataInputStream xdinl=new DataInputStream(sl.getInputStream());
dinl=xdinl;
@@ -24,23 +24,27 @@ public class ServiceElement {
procs.put(21586, "HTTP");
procs.put(20545, "HTTP");
}
public String proc;
public String name;
public String protocol;
public IPPort ipport;
public ServiceElement(String ini) throws UnknownHostException {
String[]t=ini.split("\\$");
if(t.length==1) {
proc="";
protocol="";
ipport=new IPPort(t[0]);
}else {
proc=t[0];
protocol=t[0];
ipport=new IPPort(t[1]);
}
}
public ServiceElement() {
// TODO 自动生成的构造函数存根
}
@Override
public String toString() {
if(proc.isEmpty())
if(protocol.isEmpty())
return ipport.toString();
return proc+"$"+ipport;
return protocol+"$"+ipport;
}
public static ServiceElement getbyproc(List<ServiceElement> services, int n) {
String proc=procs.get(n);
@@ -49,7 +53,7 @@ public class ServiceElement {
Iterator<ServiceElement>sei=services.iterator();
while (sei.hasNext()) {
ServiceElement serviceElement = (ServiceElement) sei.next();
if(serviceElement.proc.isEmpty()||serviceElement.proc.equals(proc))
if(serviceElement.protocol.isEmpty()||serviceElement.protocol.equals(proc))
return serviceElement;
}
}
+34
View File
@@ -0,0 +1,34 @@
package org.kne.ui;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.plaf.metal.MetalTabbedPaneUI;
public class KTabUI extends MetalTabbedPaneUI{
@Override
public void paint(Graphics g, JComponent c) {
}
@Override
protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) {
}
@Override
protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h,
boolean isSelected) {
}
}
+117 -23
View File
@@ -91,6 +91,12 @@ public class XFrame extends JFrame {
super.setIconImage(image);
repaint();
}
public JPanel getTitlepanel() {
return titlepanel;
}
public JLabel getTitlelabel() {
return titlelabel;
}
public void setTitleColor(Color c) {
titlepanel.setBackground(c);
repaint();
@@ -141,8 +147,11 @@ public class XFrame extends JFrame {
@Override
public void mouseDragged(MouseEvent e) {
Point p=e.getLocationOnScreen();
if(xb) {
if (!isResizable())
return;
XFrame.this.setLocation(XFrame.this.getX(),p.y-delta.y);
XFrame.this.setSize(XFrame.this.getWidth(), total.y-(p.y-delta.y));
}else {
@@ -169,6 +178,8 @@ public class XFrame extends JFrame {
@Override
public void mouseDragged(MouseEvent e) {
if (!isResizable())
return;
Point p=e.getLocationOnScreen();
XFrame.this.setLocation(p.x-delta.x,p.y-delta.y);
XFrame.this.setSize( total.x-(p.x-delta.x),total.y-(p.y-delta.y));
@@ -195,6 +206,8 @@ public class XFrame extends JFrame {
@Override
public void mouseDragged(MouseEvent e) {
if (!isResizable())
return;
Point p=e.getLocationOnScreen();
XFrame.this.setLocation(XFrame.this.getX(),p.y-delta.y);
XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), total.y-(p.y-delta.y));
@@ -221,6 +234,8 @@ public class XFrame extends JFrame {
@Override
public void mouseDragged(MouseEvent e) {
if (!isResizable())
return;
Point p=e.getLocationOnScreen();
XFrame.this.setLocation(p.x-delta.x,XFrame.this.getY());
XFrame.this.setSize( total.x-(p.x-delta.x),p.y+delta0.y-XFrame.this.getY());
@@ -246,6 +261,8 @@ public class XFrame extends JFrame {
@Override
public void mouseDragged(MouseEvent e) {
if (!isResizable())
return;
Point p=e.getLocationOnScreen();
XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), p.y+delta0.y-XFrame.this.getY());
@@ -271,6 +288,8 @@ public class XFrame extends JFrame {
@Override
public void mouseDragged(MouseEvent e) {
if (!isResizable())
return;
Point p=e.getLocationOnScreen();
XFrame.this.setLocation(p.x-delta.x,XFrame.this.getY());
XFrame.this.setSize( total.x-(p.x-delta.x),XFrame.this.getHeight());
@@ -297,6 +316,8 @@ public class XFrame extends JFrame {
@Override
public void mouseDragged(MouseEvent e) {
if (!isResizable())
return;
Point p=e.getLocationOnScreen();
XFrame.this.setSize(p.x+delta0.x-XFrame.this.getX(), XFrame.this.getHeight());
@@ -323,6 +344,8 @@ public class XFrame extends JFrame {
@Override
public void mouseDragged(MouseEvent e) {
if (!isResizable())
return;
Point p=e.getLocationOnScreen();
XFrame.this.setSize(XFrame.this.getWidth(), p.y+delta0.y-XFrame.this.getY());
@@ -336,24 +359,46 @@ public class XFrame extends JFrame {
SpringLayout sl_titlepanel = new SpringLayout();
titlepanel.setLayout(sl_titlepanel);
JButton close = new JButton("");
close.setBackground(Color.WHITE);
JLabel close = new JLabel("");
close.setHorizontalAlignment(SwingConstants.CENTER);
close.setBackground(invisible);
close.setForeground(Color.WHITE);
close.setIcon(new ImageIcon(XFrame.class.getResource("/assets/close.png")));
sl_titlepanel.putConstraint(SpringLayout.NORTH, close, 0, SpringLayout.NORTH, titlepanel);
sl_titlepanel.putConstraint(SpringLayout.WEST, close, -46, SpringLayout.EAST, titlepanel);
sl_titlepanel.putConstraint(SpringLayout.SOUTH, close, 0, SpringLayout.SOUTH, titlepanel);
sl_titlepanel.putConstraint(SpringLayout.EAST, close, 0, SpringLayout.EAST, titlepanel);
close.setBorderPainted(false);
close.setContentAreaFilled(false);
close.setFocusPainted(false);
close.addActionListener(new ActionListener() {
close.addMouseListener(new MouseListener() {
@Override
public void actionPerformed(ActionEvent e) {
public void mouseClicked(MouseEvent e) {
XFrame.super.processWindowEvent(new WindowEvent(XFrame.this, WindowEvent.WINDOW_CLOSING));
}
@Override
public void mousePressed(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseExited(MouseEvent e) {
// TODO 自动生成的方法存根
}
});
titlepanel.add(close);
iconi = new JLabel("");
@@ -365,7 +410,8 @@ public class XFrame extends JFrame {
iconi.setOpaque(false);
iconi.setBackground(invisible);
titlepanel.add(iconi);
JButton maxium = new JButton("");
JLabel maxium = new JLabel("");
maxium.setHorizontalAlignment(SwingConstants.CENTER);
maxium.setForeground(Color.WHITE);
maxium.setBackground(Color.WHITE);
maxium.setIcon(new ImageIcon(XFrame.class.getResource("/assets/maxium.png")));
@@ -373,23 +419,49 @@ public class XFrame extends JFrame {
sl_titlepanel.putConstraint(SpringLayout.WEST, maxium, -46, SpringLayout.WEST, close);
sl_titlepanel.putConstraint(SpringLayout.SOUTH, maxium, 0, SpringLayout.SOUTH, titlepanel);
sl_titlepanel.putConstraint(SpringLayout.EAST, maxium, 0, SpringLayout.WEST, close);
maxium.setBorderPainted(false);
maxium.setContentAreaFilled(false);
maxium.setFocusPainted(false);
maxium.addActionListener(new ActionListener() {
//maxium.setBorderPainted(false);
maxium.setBackground(invisible);
maxium.addMouseListener(new MouseListener() {
@Override
public void actionPerformed(ActionEvent e) {
public void mouseClicked(MouseEvent e) {
if (!isResizable())
return;
int s=XFrame.this.getExtendedState();
if(s==JFrame.NORMAL)
XFrame.this.setExtendedState(JFrame.MAXIMIZED_BOTH);
if(s==JFrame.MAXIMIZED_BOTH)
XFrame.this.setExtendedState(JFrame.NORMAL);
}
@Override
public void mousePressed(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseExited(MouseEvent e) {
// TODO 自动生成的方法存根
}
});
titlepanel.add(maxium);
JButton minium = new JButton("");
JLabel minium = new JLabel("");
minium.setHorizontalAlignment(SwingConstants.CENTER);
minium.setForeground(Color.WHITE);
minium.setBackground(Color.WHITE);
minium.setIcon(new ImageIcon(XFrame.class.getResource("/assets/minium.png")));
@@ -397,14 +469,36 @@ public class XFrame extends JFrame {
sl_titlepanel.putConstraint(SpringLayout.WEST, minium, -46, SpringLayout.WEST, maxium);
sl_titlepanel.putConstraint(SpringLayout.SOUTH, minium, 0, SpringLayout.SOUTH, close);
sl_titlepanel.putConstraint(SpringLayout.EAST, minium, 0, SpringLayout.WEST, maxium);
minium.setContentAreaFilled(false);
minium.setBorderPainted(false);
minium.setFocusPainted(false);
//minium.setRolloverEnabled(false);
minium.addActionListener(new ActionListener() {
minium.setBackground(invisible);
minium.addMouseListener(new MouseListener() {
@Override
public void actionPerformed(ActionEvent e) {
public void mouseReleased(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mousePressed(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseExited(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO 自动生成的方法存根
int s=XFrame.this.getExtendedState();
if(s!=JFrame.ICONIFIED) {
state=s;
+118
View File
@@ -0,0 +1,118 @@
package org.kne.ui;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import javax.swing.JScrollBar;
public class YScrollPane extends JPanel {
private JPanel settings;
public YScrollPane(int contentx){
this(contentx,BorderLayout.EAST);
}
public YScrollPane(int contentx, String d) {
setLayout(new BorderLayout(0, 0));
setBackground(Color.WHITE);
JScrollBar scrollBar = new JScrollBar();
add(scrollBar,d);
JPanel panel = new JPanel();
add(panel, BorderLayout.CENTER);
panel.setLayout(null);
panel.setOpaque(false);
settings = new JPanel();
settings.setOpaque(false);
settings.setMaximumSize(new Dimension(contentx, Integer.MAX_VALUE-10));
settings.setPreferredSize(new Dimension(contentx, 0));
settings.setSize(new Dimension(contentx, 0));
FlowLayout flowLayout = (FlowLayout) settings.getLayout();
flowLayout.setAlignment(FlowLayout.LEFT);
panel.add(settings);
settings.addContainerListener(new ContainerListener() {
@Override
public void componentRemoved(ContainerEvent e) {
int maxv=0;
for (int i = 0; i<settings.getComponentCount(); i++) {
Component comp=settings.getComponent(i);
int tmp=comp.getY()+comp.getHeight();
maxv+=tmp+flowLayout.getVgap();
}
settings.setSize(settings.getWidth(), maxv);
flowLayout.layoutContainer(settings);
scrollBar.setMaximum(settings.getHeight());
scrollBar.setMinimum(0);
scrollBar.setVisibleAmount(panel.getHeight());
updateUI();
}
@Override
public void componentAdded(ContainerEvent e) {
int maxv=0;
for (int i = 0; i<settings.getComponentCount(); i++) {
Component comp=settings.getComponent(i);
int tmp=comp.getHeight();
maxv+=tmp+flowLayout.getVgap();
}
settings.setSize(settings.getWidth(), maxv);
flowLayout.layoutContainer(settings);
scrollBar.setMaximum(settings.getHeight());
scrollBar.setMinimum(0);
scrollBar.setVisibleAmount(panel.getHeight());
updateUI();
}
});
scrollBar.addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
settings.setLocation(settings.getX(), -scrollBar.getValue());
}
});
panel.addComponentListener(new ComponentListener() {
@Override
public void componentShown(ComponentEvent e) {
}
@Override
public void componentResized(ComponentEvent e) {
settings.setLocation(panel.getWidth()/2-settings.getWidth()/2, settings.getY());
flowLayout.layoutContainer(settings);
scrollBar.setMaximum(settings.getHeight());
scrollBar.setMinimum(0);
scrollBar.setVisibleAmount(panel.getHeight());
}
@Override
public void componentMoved(ComponentEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void componentHidden(ComponentEvent e) {
// TODO 自动生成的方法存根
}
});
}
public JPanel getView() {
return settings;
}
}