[英]Java How to: proper GUI coding?
这是一个很长的,下面是我的“主要”类,它拥有我的大部分UI逻辑和所有的听众等。无论如何你可以看到我把很多代码插入到一个类中,整个事情似乎是不可读的但它确实有效。
我在一个单独的包中有一个单独的GUI类,我在我的initUI()函数中调用该类,然后从这里引用所有组件并编写将这些组件作为参数的方法,并为这些组件添加特定的监听器。 我还引用方法setter / getters的每个GLOBAL变量而不是直接引用它们。 正如你所看到的那样,函数列表在initUI()中堆积起来,我甚至都不在那里。
我猜这甚至不是专业的方法,你能不能给我提供新手提示,例子和建议如何改进所有这些代码,因为即使这一切都有效,因为它应该是非常非常丑陋的看,有没有书籍或教程解释如何编写更大的应用程序的方法。
即使我在这个GUI中途完成这个GUI我喜欢尝试,并且我被告知JavaFX对于使用Java GUI更好,而且你获得的代码更令人愉快,就像你在Java Swing中得到的那样但在另一方面,JavaFX有很多关于其尚未完全准备好使用的投票。
无论如何这里是我的代码:
package ept.controller;
import ept.view.EPTMain;
import ept.model.EPTEvent_Model;
import ept.model.EPTLocal_Model;
import ept.model.EPTModule_Model;
import java.awt.Font;
import java.awt.MouseInfo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.DefaultListModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
public class EPTIndex_Controler {
public EPTIndex_Controler() {
initUI();
}
//Globals
protected String selectedTower = null;
protected Integer selectedModules = 0;
public void setSelectedTower(String tower){
this.selectedTower = tower;
}
public String getSelectedTower(){
return this.selectedTower;
}
public void setSelectedModules(Integer i){
this.selectedModules += i;
}
public void decrementSelectedModule(Integer i){
this.selectedModules -= 1;
}
public Integer getSelectedModules(){
return this.selectedModules;
}
private void initUI(){
EPTMain runnable = new EPTMain();
JLabel towerName = runnable.tower_name;
JComboBox towerSelect = runnable.tower_selection;
JLabel shield_ = runnable.shield_amount;
JLabel armor_ = runnable.armor_amount;
JLabel em_ = runnable.em_amount;
JLabel th_ = runnable.th_amount;
JLabel kn_ = runnable.kn_amount;
JLabel ex_ = runnable.ex_amount;
JProgressBar cpu_bar = runnable.cpu_bar;
JProgressBar cap_bar = runnable.capacitor_bar;
JList mod_browse = runnable.module_browser;
JList mod_select = runnable.selected_modules;
Font decode = new Font("monospaced", Font.PLAIN, 12);
mod_select.setFont(decode);
//mod_browse.setFont(decode);
setTowerName(towerName, towerSelect, shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
removeTower(towerName, shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
addModule(mod_browse, mod_select, shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
removeModule(mod_select, shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
runnable.setExtendedState(EPTMain.MAXIMIZED_BOTH);
runnable.setVisible(true);
}
protected DefaultListModel struct = new DefaultListModel();
private void removeModule(final JList select, final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
select.addMouseListener(new MouseListener(){
@Override
public void mouseClicked(MouseEvent e) {
String removable = select.getSelectedValue().toString();
if(e.getClickCount() == 2 && removable.equals("No modules have been selected") == false){
String cap = select.getSelectedValue().toString().substring(61, 70).trim();
String cpu = select.getSelectedValue().toString().substring(75).trim();
Integer D_CAP = Integer.valueOf(cap).intValue();
Integer D_CPU = Integer.valueOf(cpu).intValue();
decConsumedCap(D_CAP);
decConsumedCpu(D_CPU);
struct.removeElement(select.getSelectedValue());
incrementVariables(shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
select.setModel(struct);
decrementSelectedModule(1);
}
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
});
}
private void addModule(final JList browse, final JList select, final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
browse.addMouseListener(new MouseListener(){
@Override
public void mouseClicked(MouseEvent e) {
String addable = browse.getSelectedValue().toString();
if(e.getClickCount() == 2 && getSelectedTower() != null && addable.charAt(0) == ' '){
String data[] = new EPTModule_Model().moduleData(addable.trim());
String module = data[0];
Integer capacitor = Integer.valueOf(data[1]).intValue(); setConsumedCap(capacitor);
Integer cpu = Integer.valueOf(data[2]).intValue(); setConsumedCpu(cpu);
String module_cap = data[1];
String module_cpu = data[2];
if(getConsumedCap()+capacitor > getCap() || getConsumedCpu()+cpu > getCpu()){
new EPTEvent_Model().eventNoCapOrCpu();
} else {
struct.addElement(String.format("> %-47s Capacitor: %-8s CPU: %s", module, module_cap, module_cpu));
select.setModel(struct);
setSelectedModules(1);
incrementVariables(shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
}
} else if (e.getClickCount() == 2 && getSelectedTower() == null){
new EPTEvent_Model().eventNoTowerSelected();
}
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
});
}
private void removeTower(final JLabel type, final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
type.addMouseListener(new MouseListener(){
@Override
public void mouseClicked(MouseEvent e) {
if(getSelectedModules() == 0){
type.setText("No Control Tower Selected");
setSelectedTower(null);
resetVariables(shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
} else {
new EPTEvent_Model().eventModuleSelected();
}
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
});
}
private void setTowerName(final JLabel type, final JComboBox type2, final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
type2.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if(getSelectedTower() != null){
new EPTEvent_Model().eventTowerSelected();
} else {
setSelectedTower(type2.getSelectedItem().toString());
new EPTDispatch_Controler(type, type2.getSelectedItem().toString());
updateVariables(shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
}
}
});
}
//Referenced Globals
protected int cap = 0;
protected int consumed_cap = 0;
protected int cpu = 0;
protected int consumed_cpu = 0;
public void setCap(int cap){
this.cap = cap;
}
public int getCap(){
return this.cap;
}
public void setCpu(int cpu){
this.cpu = cpu;
}
public int getCpu(){
return this.cpu;
}
public void resetConsumed(){
this.consumed_cap = 0;
this.consumed_cpu = 0;
}
public void setConsumedCap(int consumed_cap){
this.consumed_cap += consumed_cap;
}
public void decConsumedCap(int consumed_cap){
this.consumed_cap -= consumed_cap;
}
public int getConsumedCap(){
return this.consumed_cap;
}
public void setConsumedCpu(int consumed_cpu){
this.consumed_cpu += consumed_cpu;
}
public void decConsumedCpu(int consumed_cpu){
this.consumed_cpu -= consumed_cpu;
}
public int getConsumedCpu(){
return this.consumed_cpu;
}
//Referenced Globals
protected int shield = 0;
protected int armor = 0;
protected double em = 00.00;
protected double th = 00.00;
protected double kn = 00.00;
protected double ex = 00.00;
public void setEm(double em){
this.em = em;
}
public double getEm(){
return this.em;
}
public void setTh(double th){
this.th = th;
}
public double getTh(){
return this.th;
}
public void setKn(double kn){
this.kn = kn;
}
public double getKn(){
return this.kn;
}
public void setEx(double ex){
this.ex = ex;
}
public double getEx(){
return this.ex;
}
public void setShield(int shield){
this.shield = shield;
}
public int getShield(){
return this.shield;
}
public void setArmor(int armor){
this.armor = armor;
}
public int getArmor(){
return this.armor;
}
private void setCL(JProgressBar t, int i){
t.setValue(i);
}
private void incrementVariables(final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
cap_bar.setMaximum(getCap());
cap_bar.setValue(getConsumedCap());
cap_bar.setString(getConsumedCap() + " / " + getCap());
cap_bar.setStringPainted(true);
cpu_bar.setMaximum(getCpu());
cpu_bar.setString(getConsumedCpu() + " / " + getCpu());
cpu_bar.setStringPainted(true);
cap_bar.setValue(getConsumedCpu());
String shieldA = String.valueOf(getShield()).toString();
shield_.setText(shieldA);
String armorA = String.valueOf(getArmor()).toString();
armor_.setText(armorA);
double e = getEm();
String emT = String.valueOf(e);
em_.setText(emT);
double t = getTh();
String thT = String.valueOf(t);
th_.setText(thT);
double k = getKn();
String knT = String.valueOf(k);
kn_.setText(knT);
double x = getEx();
String exT = String.valueOf(x);
ex_.setText(exT);
}
private void updateVariables(final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
String data[] = new EPTLocal_Model().serializeData(getSelectedTower());
Integer capA = Integer.valueOf(data[1]).intValue();
setCap(capA);
cap_bar.setMaximum(getCap());
cap_bar.setString(getConsumedCap() + " / " + getCap());
cap_bar.setValue(getConsumedCap());
cap_bar.setStringPainted(true);
Integer cpuA = Integer.valueOf(data[2]).intValue();
setCpu(cpuA);
cpu_bar.setMaximum(getCpu());
cpu_bar.setString(getConsumedCpu() + " / " + getCpu());
cpu_bar.setValue(getConsumedCpu());
cpu_bar.setStringPainted(true);
Integer shieldAmount = Integer.valueOf(data[3]).intValue();
setShield(shieldAmount);
shield_.setText(data[3]);
Integer armorAmount = Integer.valueOf(data[4]).intValue();
setArmor(armorAmount);
armor_.setText(data[4]);
Double emT = Double.valueOf(data[5]).doubleValue();
setEm(emT);
em_.setText(data[5]);
Double thT = Double.valueOf(data[6]).doubleValue();
setTh(thT);
th_.setText(data[6]);
Double knT = Double.valueOf(data[7]).doubleValue();
setKn(knT);
kn_.setText(data[7]);
Double exT = Double.valueOf(data[8]).doubleValue();
setEx(exT);
ex_.setText(data[8]);
}
private void resetVariables(final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
resetConsumed();
setCap(0);
cap_bar.setMaximum(getCap());
cap_bar.setString(getConsumedCap() + " / " + getCap());
cap_bar.setStringPainted(true);
setCpu(0);
cpu_bar.setMaximum(getCpu());
cpu_bar.setString(getConsumedCpu() + " / " + getCpu());
cpu_bar.setStringPainted(true);
setShield(0);
shield_.setText("0");
setArmor(0);
armor_.setText("0");
setEm(00.00);
em_.setText("00.00");
setTh(00.00);
th_.setText("00.00");
setKn(00.00);
kn_.setText("00.00");
setEx(00.00);
ex_.setText("00.00");
}
}
首先要做的事情是......永远不要使用Netbeans GUI来拖放组件。 它容易但后来会引发很多问题。 如果您调整窗口大小,则所有组件都不会正确调整大小,如果您想稍后动态添加组件,则会受到影响。 而是使用一个好的布局管理器。 与jdk一起使用的那些很难使用,试试这个: http : //www.jgoodies.com/freeware/forms/
接下来,如果你正在制作一个巨大的框架,最好将它拆分成面板。 每个小组在一个单独的类中。 这将允许您轻松管理小型GUI。 不要使用匿名内部类乱丢代码。 而是让类实现一个侦听器并使用actionPerformed()方法中的if块来处理您的操作。 使您的代码具有一点可读性。 否则使用Actions并传递它们。
做所有长时间运行的东西,如访问数据库或读取/写入另一个线程上的文件。 否则您的GUI将冻结。 使用Swing Worker - http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html这将迫使您在某种程度上以MVC方式思考。 之后,你可以将你的课程分开,这样M,V和C都是分开的。
在构建应用程序时,关注点分离是至关重要的。
实现这一目标的常见设计模式是模型 - 视图 - 控制器 ,它是GUI应用程序的标准设计方法。 Swing构建于此之上,它“迫使”开发人员在设计时考虑到这种方法。
因此,如果您需要有关如何改进代码的提示,您应该研究MVC设计模式(Google中的数千个示例)并重构您的代码以使用它。
简而言之,您将拥有3个逻辑上独立的模块, Model
将封装您的数据/状态,您的View
将封装您的UI和Controller
,它将成为您应用程序的主要驱动程序。
一旦您将代码重构为此模式,您将看到代码如何更干净,可维护且易于扩展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.