将布尔值从主类移动到单独的类的错误

时间:2013-07-24 20:19:24

标签: java swing

我一直在为我的几个朋友安装一个安装程序,用于向Minecraft添加mod。 我从项目中删除了所有静态变量和方法(当然主要方法除外),只是将对象添加到main方法中,所以我可以从其他类调用方法(其他类中的方法不是静态的[感谢MadProgrammer向我提出这个建议:D])现在当我尝试在我的单独类(FileHandling)中调用一个布尔值时,无论如何都会返回false,但是如果我在主类中打印出布尔值,它会在true和false之间变换(喜欢它应该) 为什么这样,我该如何解决?

以下是我之前发生的错误,但不是此帖的“主要想法”

我创建了一个名为fileChooserCheck的方法(在FileHandling类中)。它的作用是获取用户由JFileChooser定义的安装目录并将其设置为modDir,或者,如果用户未指定,则将安装目录设置为默认目录,即File'defaultDir' 。每当我运行方法fileChooserCheck时,它都不会更改Path modDir,当我尝试调用它时(modDir)它返回null。

如何才能使fileChooserCheck实际更改Path modDir?

如果你在我的代码中看到任何你是草率和/或可能/需要改进的东西,请告诉我,我只用Swing编程了几天,Java已经用了将近一周[我只知道另一种编程语言[非常基本]]

编辑:更新并缩小了代码

主类

public class MainInstaller extends JFrame {

//File moddir;
Path modDir;
URI bioForums = URI.create("http://bio-mc.com/forum");
String mcDir = "C://Users//" + username + "//AppData//Roaming//.minecraft";
File defaultDir = new File("C://Users//" + username +  "//AppData//Roaming//.minecraft");
Font consoleFont = new Font("", Font.PLAIN, 13 + 1/2);
Font checkFont = new Font("", Font.PLAIN, 14 + 1/2);
String[] minimapsArray = { "REI's Minimap", "Zan's Minimap" }; //An array of optifine versions, get manually later
Object minimap;
int yInterval = 22;
boolean enabled = false;
boolean optifine, invtweaks, armorhud, statuseffecthud, tabbychat, spc, chatbubbles, map = true;
boolean fcLaunched = false;

JPanel installPanel, modsPanel, consolePanel;
Box box, box1;
JLabel title;
JLabel modsel;
JLabel author;
JTabbedPane tabbedpane = new JTabbedPane();
JComboBox<?> minimaps; //The drop down menus to select the versions of optifine and  invtweaks
JButton installButton;
JButton fileButton, forumButton, threadButton;
JTextArea console;
JTextField mcdir; 
JFileChooser fc;

public MainInstaller() { //MainInstaller Constructor

    //The First Tab(Installer)
    installPanel = new JPanel();
    installPanel.setLayout(null);
    Insets insets = installPanel.getInsets();
    installButton = new JButton("Install!");
    installButton.setFont(new Font("", Font.PLAIN, 20));
    Dimension size = installButton.getPreferredSize();

    mcdir = new JTextField();
    mcdir.setText("C:/Users/" + username + "/AppData/Roaming/.minecraft");
    mcdir.setFont(new Font("", Font.PLAIN, 13));
    size = mcdir.getPreferredSize();
    mcdir.setBounds(139 + insets.left, 80 + insets.top, size.width + 5, size.height);
    mcdir.setEditable(false);

    fileButton = new JButton("...");
    size = fileButton.getPreferredSize();
    fileButton.setBounds(mcdir.getX() + 280, mcdir.getY() - 1 + insets.top, size.width, size.height + 3);   
    fileButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent e) {
            fcLaunched = true;
            //Create the FileChooser and define it a bit    
            if (fc == null) {
                    fc = new JFileChooser("C://Users//" + username + "//AppData//Roaming//.minecraft");
                        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                }

            //Show the file Chooser
            int returnVal = fc.showOpenDialog(fileButton);

            fc.setSelectedFile(defaultDir);

            modDir = moddir.toPath(); //Changed what was previously 'moddir.toPath();' into what it is now b/c 'moddir' is a String type, not a File type

            //Process the results
            if(returnVal == JFileChooser.APPROVE_OPTION) {
                mcdir.setText(fc.getSelectedFile().getPath());
            } 
        }
    });

    installButton.setBounds(139 + insets.left, mcdir.getY() + 50 + insets.top, mcdir.getWidth() + fileButton.getWidth(), size.height + 40);

    installPanel.add(author);
    installPanel.add(forumButton);
    installPanel.add(threadButton);
    installPanel.add(installButton);
    installPanel.add(mcdir);
    installPanel.add(fileButton);

    //The Second Tab(Mod Selection)
    modsPanel = new JPanel();
    modsPanel.setLayout(null);
    insets = modsPanel.getInsets();
    JLabel modsel = new JLabel("Select the mods you installed");
    modsel.setFont(new Font("", Font.BOLD, 15));
    size = modsel.getPreferredSize();
    modsel.setBounds(5 + insets.left, 2 + insets.top, size.width + 15, size.height); 

    //Adds all the mod checkboxes

    JCheckBox invBox = new JCheckBox("InvTweaks");
    invBox.setFont(checkFont);
    size = invBox.getPreferredSize();
    invBox.setBounds(2 + 1/2 + insets.left, 2 + (yInterval*2) + 1/2 + insets.top, size.width, size.height); //Y = 44
    invBox.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            invtweaks = !invtweaks;
        }
    });

    modsPanel.add(modsel);
    modsPanel.add(invBox);
    modsPanel.add(mapBox);

    tabbedpane.addTab("Installer", installPanel);
    tabbedpane.addTab("Mod Selection", modsPanel);

    //Add everything to the frame
    add(box, BorderLayout.NORTH);
    add(tabbedpane);
}

public static void main(String[] args) throws IOException { //Main Method

    final MainInstaller frame = new MainInstaller();
    Insets insets = frame.getInsets();
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    frame.setSize(600, 400);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    frame.setResizable(false);

    final FileHandling file = new FileHandling();
    file.createBaseFolder();
    file.copyMods();

    frame.installButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if(frame.invtweaks == false) {
                JOptionPane.showMessageDialog(frame, "No mods are enabled");
            } else {
                // (?) Install mods here?
                try {
                    file.copyMods();
                    System.out.println("Installing Mods");
                    System.out.println("Source: " + file.invSource);
                    System.out.println("Target:" + file.invTarget);

                } catch (IOException e1) {
                    e1.printStackTrace();
                    System.out.println("Error!" + e);

                }
            }
        }});
}

}

FileHandling Class

public class FileHandling {
MainInstaller mi = new MainInstaller();

Path modDir = mi.modDirPath;
Path source = Paths.get("C://Users//Gannon//Desktop//Java//workspace//ModPack Installer//test.txt");
Path target = Paths.get("C://Users");

Path invSource = Paths.get("mods//invtweaks.jar");
Path invTarget = Paths.get(mi.modDirPath + "//InventoryTweaks-MC1.6.2-1.55-b56.jar");

public void fileChooserCheck() {
    if(mi.fcLaunched == false) {
        mi.modDirPath = mi.defaultDir.toPath();
        System.out.println("Unchanged: " + mi.modDirPath);
    } else if(mi.fcLaunched == true) {
        mi.modDirPath = mi.fc.getSelectedFile().toPath();
        System.out.println("Changed: " + mi.modDirPath);
    }
}

public void copyMods() throws IOException {
    fileChooserCheck();
    try {
        if(mi.invtweaks == true) {
            Files.copy(invSource, invTarget);
            System.out.println("Trying to copy!");
        } else if(mi.invtweaks == false ) {
            System.out.println("InvTweaks isn't selected!");
        }

    } catch (IOException e) {
        System.out.println("The Copying Failed!" + e);
    }
}

}

2 个答案:

答案 0 :(得分:1)

在主类中定义modDir,但从不为其赋值。你确实有这条线,但它被注释掉了:

//modDir = moddir.toPath();

另外我想警告你,有两个名字名称的变量,但不同的情况是个坏主意:

String moddir;
Path modDir;

更好的是:

String modDir
Path modDirPath

答案 1 :(得分:1)

我在跟踪这里发生的事情时遇到了一些麻烦,但是我有点担心你要创建两个完全独立的MainInstaller类实例:在MainInstaller的run方法中创建一个('frame'),第二个('mi')作为FileHandler类定义中的字段创建。由于MainInstaller中的所有字段都不是静态的,因此可以通过在一个实例中更改布尔值并在另一个实例中检查相同的布尔值来轻松获取引用。

对此问题的快速测试可能是将某些字段(例如布尔值)指定为静态并适当地引用它们。但是,如果是我,我强烈考虑将MainInstaller类重新定义为单例。我会通过试图解释我的意思来故意揭露我在这里的经验:

  • 将一个名为'instance'的MainInstaller类型的私有静态字段添加到MainInstaller类定义中,将其初始化为null。
  • 添加一个返回名为'getinstance'的MainInstaller对象的公共静态方法(没有args)
  • 此方法应检查'instance'字段是否为null - 如果是,则将其定义为MainInstaller的新实例。然后,只需返回'instance'。
  • 然后,只要您需要定义/访问MainInstaller对象,请通过'getInstance'方法执行此操作。

这里的优点是你仍然可以在必要时使用非静态字段和方法,但要确保没有多个实例浮动在你不期望的地方,我愿意下注您不打算创建MainInstaller的多个实例。

  • 我忘了提一下,通常你也会把你的构造函数设为私有,只是为了确保没有其他类可以创建其他实例,而应该使用getInstance方法。