【问题标题】:Implementing a general switch statement in Java在 Java 中实现一个通用的 switch 语句
【发布时间】:2013-02-26 11:50:26
【问题描述】:

我有一个 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


                }

            }
        });

【问题讨论】:

  • 不清楚区别是什么 - 你说“它们之间的区别是变量 x”但你的 pst.setInt(1, x); 已经这样做了......

标签: java swing switch-statement jslider


【解决方案1】:

考虑到每个switch子句的代码都是一样的,为什么不把你的switch替换成

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

编辑:

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

【讨论】:

  • @NominSim: 这就是这样做的,x 值已经从滑块中读取,因此查找代码可以使用该x 值,进行数据库查找然后更新mineralPolarmineralCrossed JLabel。这是由if 块保护的原因是因为他的代码只会对值1..360 进行数据库查找,这正是if 所做的。
  • @NominSim:这让投票有点苛刻,你不觉得吗?
  • @To all:我没有考虑过使用for 语句,因为我从switch 开始并没有考虑到大量的情况。这很容易,但由于代码量很大,对我来说很模棱两可。谢谢大家,今天我再次了解到少即是多:)。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    您可以使用选定的值调用子程序

    类似changeLabelImgTo(int count);

    【讨论】:

      【解决方案4】:

      把你的代码解压成一个方法,传入变量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) {
          }
      
      }
      

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-25
          • 1970-01-01
          • 2011-11-12
          • 1970-01-01
          • 1970-01-01
          • 2019-04-07
          相关资源
          最近更新 更多