我刚开始学习Java(:))很抱歉,如果这对你们中的一些人来说显而易见:
我想创建一个程序,我可以将一个文件移动到另一个目录(我懒得拖放),程序运行正常并且自己花钱。但是我想添加一个主菜单类型的屏幕,我可以选择放入哪个文件目录(也可以正常工作)。
所以我的问题:如何在Move类中使用“source”变量?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Browse {
public static void main(String arg[])throws IOException{ {
JFrame frame1 = new JFrame();
JPanel panel1 = new JPanel();
JButton button1 = new JButton("press");
frame1.add(panel1);
frame1.setSize(400, 400);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setVisible(true);
panel1.add(button1);
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("."));
chooser.setDialogTitle("choosertitle");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
System.out.println("getCurrentDirectory(): " + chooser.getCurrentDirectory());
System.out.println("getSelectedFile() : " + chooser.getSelectedFile());
} else {
System.out.println("No Selection ");
}
File source = chooser.getSelectedFile();
}});}}
}
public class Move {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("."));
chooser.setDialogTitle("choosertitle");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
System.out.println("getCurrentDirectory(): " + chooser.getCurrentDirectory());
System.out.println("getSelectedFile() : " + chooser.getSelectedFile());
} else {
System.out.println("No Selection ");
}
File source =chooser.getSelectedFile();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
if(!source.exists()){
System.out.println("File or directory does not exist.");
System.exit(0);
}
int a = 0;
String dest = ("C:/Users/David/Desktop/test");
System.out.println(dest);
File destination = new File(dest);
int num = 1;
if(num == 0 || num==1){
copyDirectory(source, destination);
a = 1;
}
if(a == 1){
System.out.println("File or directory moved successfully.");
JFrame frame3 = new JFrame();
JPanel panel2 = new JPanel(new GridBagLayout());
frame3.getContentPane().add(panel2, BorderLayout.NORTH);
GridBagConstraints c= new GridBagConstraints();
JLabel moved = new JLabel("Con Gratz map has been moved :) (hopfully)");
c.gridx = 10;
c.gridy =10;
c.insets = new Insets(10,10,10,10);
frame3.add(panel2);
frame3.setSize(400, 400);
frame3.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame3.setVisible(true);
panel2.add(moved);
if(!delete(source)){
throw new IOException("Unable to delete original folder");
}
}
else if(a == 0){
System.exit(0);
}}
}
public static void copyDirectory(File sourceDir, File destDir)
throws IOException{
if(!destDir.exists()){
destDir.mkdir();
}
File[] children = sourceDir.listFiles();
for(File sourceChild : children){
String name = sourceChild.getName();
File destChild = new File(destDir, name);
if(sourceChild.isDirectory()){
copyDirectory(sourceChild, destChild);
}
else{
copyFile(sourceChild, destChild);
}
}
}
public static void copyFile(File source, File dest) throws IOException{
if(!dest.exists()){
dest.createNewFile();
}
InputStream in = null;
OutputStream out = null;
try{
in = new FileInputStream(source);
out = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int len;
while((len = in.read(buf)) > 0){
out.write(buf, 0, len);
}
}
finally{
in.close();
out.close();
}
}
public static boolean delete(File resource) throws IOException{
if(resource.isDirectory()){
File[] childFiles = resource.listFiles();
for(File child : childFiles){
delete(child);
}
}
return resource.delete();
}
}
两个班级分开工作,我可能删除了一条重要的路线......但它们确实有用。
thansk求助:)
(如果有人在代码中发现任何可以改进的内容,请不要害羞:))
答案 0 :(得分:0)
您可以将source
分配到Move
中的constructor
班级。像这样:
public class Move
{
private File f;
// Constructor taking a File as parameter
public Move(File f)
{
// Assign File to this instance of Move
this.f = f;
}
public void someMethod()
{
// Abuse the File class 'f' here
}
}
然后在main
执行以下操作, 后检索source
。
File source = ...
Move m = new Move(source);
答案 1 :(得分:0)
尝试在main方法之外声明你的“source”变量而没有任何限定符,因此默认情况下变量将是包私有(假设你的两个类都在同一个包中)。如果不是,您可以始终创建私有实例并添加get方法来访问该实例。
答案 2 :(得分:0)
我认为这就是你要做的事情:
import javax.swing.*;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
public class Browse {
static class CopierThread extends Thread {
private final Component gui_;
private final File source_;
private final File dest_;
CopierThread(Component gui, File source, File dest) {
gui_ = gui;
source_ = source;
dest_ = dest;
}
@Override
public void run() {
try {
copyDirectory(source_, dest_);
} catch (IOException ioe) {
ioe.printStackTrace();
JOptionPane.showMessageDialog(gui_, "The copy of "
+ source_.getAbsolutePath() + " to "
+ dest_.getAbsolutePath()
+ " failed. See console for more details.",
"Copy failed", JOptionPane.ERROR_MESSAGE);
}
}
}
public static void main(String arg[]) {
final JFrame frame1 = new JFrame();
JPanel panel1 = new JPanel();
JButton button1 = new JButton("press");
frame1.add(panel1);
frame1.setSize(400, 400);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame1.setVisible(true);
panel1.add(button1);
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JFileChooser chooser = new JFileChooser();
chooser.setCurrentDirectory(new java.io.File("."));
chooser.setDialogTitle("choosertitle");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
System.out.println("getCurrentDirectory(): "
+ chooser.getCurrentDirectory());
System.out.println("getSelectedFile() : "
+ chooser.getSelectedFile());
File source = chooser.getSelectedFile();
File dest = new File("C:/Users/David/Desktop/test");
Thread thread = new CopierThread(frame1, source, dest);
thread.start();
} else {
System.out.println("No Selection ");
}
}
});
}
public static void copyDirectory(File sourceDir, File destDir) throws IOException {
if (!destDir.exists()) {
destDir.mkdir();
}
File[] children = sourceDir.listFiles();
for(File sourceChild:children) {
String name = sourceChild.getName();
File destChild = new File(destDir, name);
if (sourceChild.isDirectory()) {
copyDirectory(sourceChild, destChild);
} else {
copyFile(sourceChild, destChild);
}
}
}
public static void copyFile(File source, File dest) throws IOException {
if (!dest.exists()) {
dest.createNewFile();
}
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(source);
try {
out = new FileOutputStream(dest);
byte[] buf = new byte[1024];
int len;
while( (len = in.read(buf)) != -1 ) {
out.write(buf, 0, len);
}
} finally {
if (out != null) out.close();
}
} finally {
if (in != null) in.close();
}
}
}
首先回答您的主要问题,有多种方法可以访问另一个对象拥有的变量。要使用它们中的任何一个,必须首先使变量成为成员变量,而不是方法变量。在我的代码上面,CopierThread有三个成员变量。如果变量不是成员变量,则只能在特殊情况下访问它。请注意,我创建了frame1
变量final
,以允许ActionListener的匿名内部类访问它。
所以你的主要问题的答案是:
成员变量可以由其他类访问,具体取决于其保护。没有其他类可以访问private
成员变量。每个其他类都可以访问public
成员变量。默认值和protected
介于两者之间,您应该查看它们。
如果在方法中定义了该类并且该变量被声明为final,则只能由另一个类访问方法变量。
创建专门用于访问成员变量的方法是常见且有用的。这是一个很好的设计实践,因为它隐藏了实现,允许执行验证规则,限制访问,并且可以通过内省轻松识别变量。
其他一些评论:
1)在事件监听器运行时,GUI没有响应。因此,你不应该在事件监听器中做任何大事。我的代码启动了一个新线程来复制文件,因此GUI事件监听器不必等待它,GUI仍然保持响应。
2)输入和输出流最终由垃圾收集器关闭,但在大型服务器VM中,这可能需要很长时间才能阻止其他程序访问文件。因此,您应始终确保使用finally块关闭流,请记住,如果构造函数本身失败,则变量将为null。
3)格式化源代码可以让每个人的生活更轻松。免费的IDE(如Eclipse)将自动为您格式化。