0

我有一个 JSlider,其值从 1 到 360。对于每个值,我想从数据库中获取图像并将其放入 JLabel。所以我有 360 个案例,其中唯一的区别是用于从数据库中获取相应图像的变量开关(参见下面的代码)。我知道我需要刷新我的代码,因为我的“解决方案”代码非常繁重。

我希望我清楚我想要存档的内容。下面是代码。

degreesSlider = new JSlider(); //my JSlider

degreesSlider.setMajorTickSpacing(10);
degreesSlider.setMaximum(360);
degreesSlider.setMinorTickSpacing(1);
degreesSlider.setOrientation(javax.swing.JSlider.VERTICAL);
degreesSlider.setPaintLabels(true);
degreesSlider.setPaintTicks(true);
degreesSlider.setSnapToTicks(true);
degreesSlider.setValue(0);

degreesSlider.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {

                int x = degreesSlider.getValue(); //get JSlider value

                int row = myJTable.getSelectedRow();
                int realIndex = myJTable.convertRowIndexToModel(row);
                String clickJTable = (myJTable.getModel().getValueAt(realIndex, 0).toString()); //detect my JTable row click

                switch (x) {

                    case 1:
                        try {
                            PreparedStatement pst = conn.prepareStatement("select pol, cros from test where degrees = ? AND id_min=?");
                            pst.setInt(1, x); //x is the only variable of the all 360 cases
                            pst.setString(2, clickJTable);
                            ResultSet rs = pst.executeQuery();

                            if (rs.next()) {
                                byte[] imageP = rs.getBytes("pol");
                                byte[] imageC = rs.getBytes("cros");

                                pol = new ImageIcon(imagepolars);
                                cros = new ImageIcon(imagecrossed);

                                mineralsPolars.setIcon(pol); //put image into JLabel
                                mineralsCrossed.setIcon(cros); //put image into JLabel
                            }
                            rs.close();
                            pst.close();
                        } catch (Exception e) {
                        }
                        break;

                    //case 2, 3, 4 ... 360 with the same code and the difference between them is the variable x


                }

            }
        });
4

5 回答 5

3

考虑到每个 switch 子句的代码都是相同的,为什么不将 switch 替换为

 if (x >= 1 && x <= 360) {
     // do the db lookup
 }

编辑:

您需要 if 语句的唯一原因是,如果您想检查滑块值 ( x) 是否在查询指定的范围内,并且正如 @NominSim 指出的那样,滑块值在您的控制范围内,因此您可能不会如果需要的话。

于 2013-02-26T11:54:39.197 回答
2

据我了解switch,您不需要声明,您只需要一个函数,该函数将根据滑块值使用正确的图标检索和更新图标。由于检索和更新图标的代码仅基于您的x值,因此将传递给新函数。要提高此类函数的性能,您可以将准备好的语句对象的创建移到此函数之外。由于为每个调用创建一个准备好的语句对象将取消准备好的语句的几乎所有好处,并且在每次调用/滑块值更改时构建这样一个沉重的对象是非常昂贵的。

我建议使用DAO对象将您的数据库逻辑封装在一个地方,并且不要使用 SQL 和数据库逻辑污染 UI 代码。这样,您将能够通过重用已创建的语句并重用代码来获得更好的性能。

于 2013-02-26T11:53:48.753 回答
1

每个 case 值必须是编译时常量/表达式,而不是变量。与 switch 语句关联的任何两个 case 常量表达式都不能具有相同的值。

您可以拥有的是调用具有选定值的子例程

就像是changeLabelImgTo(int count);

于 2013-02-26T11:58:25.353 回答
0

将代码提取到方法中并传入变量x

public void stateChanged(ChangeEvent evt) {
    ...
    fetchImage(x);
    ...
}


private void fetchImage(int x) {

    try {
        PreparedStatement pst = conn.prepareStatement("select pol, cros from test where degrees = ? AND id_min=?");
        pst.setInt(1, x); //x is the only variable of the all 360 cases
        pst.setString(2, clickJTable);
        ResultSet rs = pst.executeQuery();

        if (rs.next()) {
            byte[] imageP = rs.getBytes("pol");
            byte[] imageC = rs.getBytes("cros");

            pol = new ImageIcon(imagepolars);
            cros = new ImageIcon(imagecrossed);

            mineralsPolars.setIcon(pol); //put image into JLabel
            mineralsCrossed.setIcon(cros); //put image into JLabel
        }
        rs.close();
        pst.close();
    } catch (Exception e) {
    }

}
于 2013-02-26T11:54:34.597 回答
0

我可能在这里遗漏了一些东西,但是如果 case 内的代码块都相同,那么你为什么要使用 switch case,毕竟?

于 2013-02-26T11:57:55.913 回答