好吧,所以我的代码“全完了”,缺少了一些关于MVC设计模式的基本知识,我应该把我的关注点分开,我没有模型层,我不知道如何在当前的情况下实现它。我的两个班是:
public class GuiPanel extends JPanel {
public ImageIcon resource01;
public ImageIcon getResource01() {
if (resource01 == null) {
resource01 = new ImageIcon(getClass().getResource("/images/reptiles99_11.jpg"));
}
return resource01;
}
public ImageIcon resource02;
public ImageIcon getResource02() {
if (resource02 == null) {
resource02 = new ImageIcon(getClass().getResource("/images/rsz_s13.jpg"));
}
return resource02;
}
private Font font;
@Override
public Font getFont() {
if (font == null) {
font = new Font("Times new Roman", Font.BOLD, 14);
}
return font;
}
private final String[] listS1 = {"-Odaberi-", "Akutni", "Hronicni"};
private int counterS1 = 0;
private JComboBox comboS1;
private JComboBox getComboS1() {
if (comboS1 == null) {
comboS1 = new JComboBox();
comboS1.setBounds(245, 135, 90, 30);
for (int i = 0; i < 3; i++) {
comboS1.addItem(listS1[counterS1++]);
}
add(comboS1);
}
return comboS1;
}
private final String[] listS2 = {"-Odaberi-", "Abdomen", "Udovi", "Glava"};
private int counterS2 = 0;
private JComboBox comboS2;
private JComboBox getComboS2() {
if (comboS2 == null) {
comboS2 = new JComboBox();
comboS2.setBounds(245, 235, 90, 30);
for (int i = 0; i < 4; i++) {
comboS2.addItem(listS2[counterS2++]);
}
add(comboS2);
}
return comboS2;
}
private ComboBoxModel[] models;
private ComboBoxModel[] getComboModels() {
if (models == null) {
models = new ComboBoxModel[5];
models[0] = new DefaultComboBoxModel(new String[]{"-Odaberi-"});
models[1] = new DefaultComboBoxModel(new String[]{"-Odaberi-", "1 - GL",
"2 - GS", "3 - GD", "4 - SL", "5 - SD", "6 - SL", "7 - DL", "8 - DS", "9 - DD"});
}
return models;
}
private JComboBox comboS3;
private JComboBox getComboS3() {
if (comboS3 == null) {
comboS3 = new JComboBox();
comboS3.setBounds(245, 335, 90, 30);
comboS3.setModel(models[0]);
comboS3.disable();
add(comboS3);
}
return comboS3;
}
private JLabel title;
private JLabel getTitleLabel() {
if (title == null) {
title = new JLabel("Aplikacija za dijagnozu bolesti");
title.setBounds(90, 40, 200, 100);
title.setFont(getFont());
add(title);
}
return title;
}
private JLabel diagnose;
private JLabel getDiagnoseLabel() {
if (diagnose == null) {
diagnose = new JLabel("Preliminarna dijagnoza :");
diagnose.setBounds(10, 420, 200, 100);
add(diagnose);
}
return diagnose;
}
private JLabel symptome01;
private JLabel getSymptome01Label() {
if (symptome01 == null) {
symptome01 = new JLabel("Vrsta bola koju osecate : ");
symptome01.setBounds(10, 100, 200, 100);
add(symptome01);
}
return symptome01;
}
private JLabel symptome02;
private JLabel getSymptome02Label() {
if (symptome02 == null) {
symptome02 = new JLabel("U kom delu tela osecate taj bol :");
symptome02.setBounds(10, 200, 200, 100);
add(symptome02);
}
return symptome02;
}
private JLabel symptome03;
private JLabel getSymptome03Label() {
if (symptome03 == null) {
symptome03 = new JLabel("Vas bol osecate u (vidi sliku) : ");
symptome03.setBounds(10, 300, 200, 100);
add(symptome03);
}
return symptome03;
}
private JLabel picture01;
private JLabel getPicture01Label() {
if (picture01 == null) {
picture01 = new JLabel(getResource01());
picture01.setBounds(400, 40, 350, 400);
add(picture01);
}
return picture01;
}
private JLabel picture02;
private JLabel getPicture02Label() {
if (picture02 == null) {
picture02 = new JLabel(getResource02());
picture02.setBounds(400, 40, 350, 400);
picture02.setVisible(false);
add(picture02);
}
return picture02;
}
private JButton reset;
private JButton getResetButton() {
if (reset == null) {
reset = new JButton("Ponovo");
reset.setBounds(640, 470, 110, 50);
reset.addActionListener(new AgainButton(getResetButton(), getComboS1(),
getComboS2(), getComboS3(), getDiagnoseField(), getPicture01Label()));
add(reset);
}
return reset;
}
private JButton calculate;
private JButton getCalculateButton() {
if (calculate == null) {
calculate = new JButton("Dijagnoza");
calculate.setBounds(400, 470, 110, 50);
calculate.addActionListener(new CalculateButton(getCalculateButton(),
getComboS1(), getComboS2(), getComboS3(), getDiagnoseField()));
add(calculate);
}
return calculate;
}
private JTextField diagnoseField;
private JTextField getDiagnoseField() {
if (diagnoseField == null) {
diagnoseField = new JTextField("");
diagnoseField.setBounds(10, 490, 350, 30);
diagnoseField.setEditable(false);
add(diagnoseField);
}
return diagnoseField;
}
public GuiPanel() {
setLayout(null);
getComboS1();
getComboS2();
getComboModels();
getComboS3();
getTitleLabel();
getDiagnoseLabel();
getSymptome01Label();
getSymptome02Label();
getSymptome03Label();
getPicture01Label();
getPicture02Label();
getResetButton();
getCalculateButton();
getDiagnoseField();
}这是主GUI类,我有一个按钮函数类,它实现了一个动作侦听器:
public class CalculateButton implements ActionListener {
private final JComboBox comboS1;
private final JComboBox comboS2;
private final JComboBox comboS3;
private final JTextField diagnoseField;
public CalculateButton(JButton calculate, JComboBox comboS1, JComboBox comboS2, JComboBox comboS3, JTextField diagnoseField) {
this.comboS1 = comboS1;
this.comboS2 = comboS2;
this.comboS3 = comboS3;
this.diagnoseField = diagnoseField;
calculate.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 1) {
diagnoseField.setText("Upala zucovoda");
} else if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 2) {
diagnoseField.setText("Cir na zeludcu");
} else if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 3) {
diagnoseField.setText("Gastritis");
} else if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 4) {
diagnoseField.setText("Renalne kolike");
} else if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 5) {
diagnoseField.setText("Divertikulitis");
} else if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 6) {
diagnoseField.setText("Rani apendicitis / pankreatitis");
} else if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 7) {
diagnoseField.setText("Apendicitis");
} else if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 8) {
diagnoseField.setText("Cistitis / bolovi u rektumu / problemi sa stolicom");
} else if (comboS1.getSelectedIndex() == 1 && comboS2.getSelectedIndex() == 1 && comboS3.getSelectedIndex() == 9) {
diagnoseField.setText("Spasma stigme");
}
}
}所有的字符串,尽管用我的母语,都应该被看作是普通的字符串。
发布于 2016-02-12 09:00:21
不要硬编码尺寸和位置。在Mac电脑上,一切看起来都不对劲。(我没有你的照片,所以我会在接下来的评论中忽略它们。)

此外,GuiPanel的用户不知道它需要有多大,而且还会被硬编码。
一种更好的布局方法是使用LayoutManagers。通过调整按钮的大小和一些边距,可以或多或少地自动获得以下结果。

你经常使用懒惰的getter模式。为什么?懒惰不会给您带来任何好处,因为您肯定需要实例化这个UI的每个组件。而且,构造函数调用这些getter纯粹是因为它们的副作用,这是非常奇怪的。相反,您应该负责构造函数中的所有实例化。
没有必要为每个JLabel创建一个实例变量。构造函数中的局部变量可以:一旦每个标签都被添加到布局中,您就不再需要引用它了。
我会以这样的方式构造UI:
import java.awt.*;
import javax.swing.*;
public class GuiPanel extends JPanel {
private JComboBox<String> typeCombo = makeComboBox("Akutni", "Hronicni"),
partCombo = makeComboBox("Abdomen", "Udovi", "Glava"),
painCombo = makeComboBox("1 - GL", "2 - GS", "3 - GD", "4 - SL", "5 - SD", "6 - SL", "7 - DL", "8 - DS", "9 - DD");
private JTextField diagnosisField = new JTextField(20);
public GuiPanel() {
this.setLayout(new BorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// Title
JLabel title = new JLabel("Aplikacija za dijagnozu bolesti", SwingConstants.CENTER);
title.setFont(new Font("Times new Roman", Font.BOLD, 14));
this.add(title, BorderLayout.NORTH);
// Questions
JPanel questions = new JPanel();
questions.setLayout(new GridLayout(0, 2, 30, 30));
questions.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
questions.add(new JLabel("Vrsta bola koju osecate :"));
questions.add(this.typeCombo);
questions.add(new JLabel("U kom delu tela osecate taj bol :"));
questions.add(this.partCombo);
questions.add(new JLabel("Vas bol osecate u (viki sliku) :"));
//this.painCombo.setEnabled(false);
questions.add(this.painCombo);
this.add(questions, BorderLayout.CENTER);
// Diagnosis and buttons
JPanel bottom = new JPanel();
bottom.setLayout(new FlowLayout());
bottom.setAlignmentY(Container.BOTTOM_ALIGNMENT);
JPanel diagnosis = new JPanel();
diagnosis.setLayout(new BoxLayout(diagnosis, BoxLayout.Y_AXIS));
diagnosis.setAlignmentX(Container.LEFT_ALIGNMENT);
diagnosis.add(new JLabel("Preliminarna dijagnoza :"));
diagnosisField.setEditable(false);
diagnosis.add(diagnosisField);
bottom.add(diagnosis);
JButton diagnosisButton = new JButton("Dijagnoza");
diagnosisButton.setMargin(new Insets(10, 10, 10, 10));
diagnosisButton.addActionListener(ActionEvent -> { diagnose(); });
bottom.add(diagnosisButton);
JButton resetButton = new JButton("Ponovo");
resetButton.setMargin(new Insets(10, 10, 10, 10));
resetButton.addActionListener(ActionEvent -> { reset(); });
bottom.add(resetButton);
this.add(bottom, BorderLayout.SOUTH);
}
private static JComboBox<String> makeComboBox(String... options) {
JComboBox<String> combo = new JComboBox<String>();
combo.addItem("-Odaberi-");
for (String opt : options) {
combo.addItem(opt);
}
return combo;
}
private void diagnose() {
String disease = DiagnosisEngine.diagnose(
this.typeCombo.getSelectedIndex() == 0 ? null : (String)this.typeCombo.getSelectedItem(),
this.partCombo.getSelectedIndex() == 0 ? null : (String)this.partCombo.getSelectedItem(),
this.painCombo.getSelectedIndex()
);
this.diagnosisField.setText(disease == null ? "" : disease);
}
private void reset() {
this.typeCombo.setSelectedIndex(0);
this.partCombo.setSelectedIndex(0);
this.painCombo.setSelectedIndex(0);
this.diagnose();
}
}诊断逻辑不应与UI相耦合。由于这个诊断任务很简单,让GuiPanel从UI中提取必要的信息,请求诊断,并显示结果。
public class DiagnosisEngine {
public static String diagnose(String type, String part, int pain) {
if ("Akutni".equals(type)) {
if ("Abdomen".equals(part)) {
switch (pain) {
case 1: return "Upala zucovoda";
case 2: return "Cir na zeludcu";
case 3: return "Gastritis";
case 4: return "Renalne kolike";
case 5: return "Divertikulitis";
case 6: return "Rani apendicitis / pankreatitis";
case 7: return "Apendicitis";
case 8: return "Cistitis / bolovi u rektumu / problemi sa stolicom";
case 9: return "Spasma stigme";
}
}
}
return null;
}
}发布于 2016-02-12 08:56:06
这看起来要好得多,因为初始化的每一个组成部分是粘在一起,在一个地方。
组件不应将自身添加到父组件中。不应该显式地知道父级。将它们添加到构造函数中,如下所示:
public GuiPanel() {
...
add(getComboS1());
add(getComboS2());
add(getComboModels());
add(getComboS3());
...
}在一个类似的问题中,我举了一个例子。作为一个复兴的问题,我将在这里提供它,所以你有一个想法,如何分开关注。
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
MyModel myModel = new MyModel();
MyFrame myFrame = new MyFrame(myModel);
myFrame.setVisible(true);
}
});
}import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class MyFrame extends JFrame {
private final MyModel myModel;
private JButton nextWordButton;
private WordTextField wordTextField;
public MyFrame(MyModel myModel) {
this.myModel = myModel;
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(getNextWordButton(), BorderLayout.WEST);
getContentPane().add(getWordTextField(), BorderLayout.CENTER);
setSize(400, 200);
}
private JButton getNextWordButton() {
if (nextWordButton == null) {
nextWordButton = new JButton("Next");
nextWordButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myModel.execute();
}
});
}
return nextWordButton;
}
private WordTextField getWordTextField() {
if (wordTextField == null) {
wordTextField = new WordTextField();
myModel.add(wordTextField);
}
return wordTextField;
}
}import java.util.HashSet;
import java.util.Set;
public class MyModel {
private static final String[] INFINITE_SENTENCE = new String[] {"This", "sentence", "will", "never", "end", "because ..."};
private int index;
private Set<MyModelListener> listeners;
public MyModel() {
this.index = 0;
this.listeners = new HashSet<>();
}
public void execute() {
this.index++;
notifyOnExecute(getWord());
}
private String getWord() {
return INFINITE_SENTENCE[this.index % INFINITE_SENTENCE.length];
}
private void notifyOnExecute(String word) {
for (MyModelListener listener: this.listeners) {
listener.onExecute(word);
}
}
public boolean add(MyModelListener l) {
l.onListenerRegistration(getWord());
return listeners.add(l);
}
public boolean remove(MyModelListener l) {
return listeners.remove(l);
}
}public interface MyModelListener {
void onExecute(String word);
void onListenerRegistration(String word);
}public class WordTextField extends JTextField implements MyModelListener {
@Override
public void onExecute(String word) {
setTextLater(word);
}
private void setTextLater(String word) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
setText(word);
}
});
}
@Override
public void onListenerRegistration(String word) {
setTextLater(word);
}
}程序是:
主要的优点是:
https://codereview.stackexchange.com/questions/119733
复制相似问题