0

因此,在我第一次使用 JavaFX 后,我被分配了一个我认为规模很大的项目,因为这只是我第二次使用 JavaFX。我必须创建一个具有基本功能的相册:添加图像、删除图像、按标题/描述/位置排序、编辑标题、拍摄日期、描述和位置的能力。好消息:我已经完成了所有这些事情,但其中一件事情已经完成。

删除照片,或者更确切地说,在从阵列中删除照片后将其从屏幕上删除imageData已被证明是复杂的。我很确定这是由于我的组织方式。我尝试为班级制作自己的“changedProperty”Album并从源头上观察它,但显然我以某种方式把它搞砸了,或者它不像我想象的那样工作。

private BooleanProperty changed = new SimpleBooleanProperty();
public final boolean getChanged(){return changed.get();}
public final void setChanged(boolean value){changed.set(value);}
public BooleanProperty changedProperty(){return changed;}

所以那是一个失败。我也尝试了一个,ObservableList但是因为它是在源代码中创建的,所以我不能obsList.remove()在我的Album班级中。同样,我可能只是错误地实施了它。

所以只是重申一下-我可以从图片中删除图像,ArrayList imageData但它们会留在图库中FlowPane

源码.java

import javafx.application.Application;
import javafx.geometry.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.File;


/**
 * Created by Alyssa on 9/27/2015.
 */
public class Source extends Application  {

    protected Stage mainWin;
    protected FlowPane gallery;
    private static boolean delete;

    public static void main(String[] args){
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception{
        Album album = new Album();

        Scene mainScene;

        for(int i = 0; i < 52;i++) {
            album.getImageData().add(new ImageData(("cards/" + String.valueOf(i + 1) + ".png"), "cardtitle" + i, "carddesc", "cardloc"));
        }

        album.getObsList().addListener(new ListChangeListener(){ 
        @Override 
        public void onChanged(ListChangeListener.Change change){ 
            refreshGallery(); } 
        });

        //FILE MENU
        Menu fileMenu = new Menu("_File");
        MenuItem addImg = new MenuItem("_Add Photo...");
        addImg.setOnAction(e -> {
            FileChooser fileChooser = new FileChooser();
            fileChooser.setTitle("Open Resource File");
            File file = fileChooser.showOpenDialog(mainWin);
            String absPath = "file:" + file.getAbsolutePath();
            absPath = absPath.replace('\\', '/');
            album.addImage(absPath, "","","");
            refreshGallery();
        });

        MenuItem exit = new MenuItem("_Exit");
        exit.setOnAction(e -> mainWin.close());
        fileMenu.getItems().addAll(addImg, new SeparatorMenuItem(), exit);

        //SORT MENU
        Menu sortMenu = new Menu("_Sort");
        MenuItem sortTitle = new MenuItem("_Title");
        sortTitle.setOnAction(e -> {
            album.sortAlbumTitle(album);
            refreshGallery();
        });
        MenuItem sortDate = new MenuItem("_Date Taken");
        sortDate.setOnAction(e -> {
            album.sortAlbumDate(album);
            refreshGallery();
        });
        MenuItem sortLoc = new MenuItem("_Location");
        sortLoc.setOnAction(e -> {
            album.sortAlbumLoc(album);
            refreshGallery();
        });

        sortMenu.getItems().addAll(sortTitle, sortDate,sortLoc);

        //HELP MENU
        Menu helpMenu = new Menu("_Help");
        MenuItem helpAbout = new MenuItem("_About");
        helpAbout.setOnAction(e -> Help.displayAbout());
        MenuItem helpHelp = new MenuItem("_Help");
        helpHelp.setOnAction(e -> Help.displayHelp());
        helpMenu.getItems().addAll(helpAbout, helpHelp);

        //MENU BAR
        MenuBar menuBar = new MenuBar();
        menuBar.getMenus().addAll(fileMenu, sortMenu, helpMenu);
        menuBar.setStyle("-fx-background-color: #383838;");

        mainWin = primaryStage;
        mainWin.setTitle("Photo Album");

        ScrollPane center = new ScrollPane();
        //center.setMinWidth(800);
        center.setFitToWidth(true);

        gallery = new FlowPane();
        gallery.setPadding(new Insets(5, 5, 5, 5));
        gallery.setAlignment(Pos.CENTER);
        gallery.setColumnHalignment(HPos.CENTER);
        gallery.setRowValignment(VPos.CENTER);
        gallery.setHgap(10);
        gallery.setVgap(10);
        gallery.setPrefWrapLength(785);

        for (int i =0 ; i < album.getImageData().size(); i++){
            gallery.getChildren().add(album.getImageData().get(i).getImageBtn());
        }

        center.setContent(gallery);

        BorderPane borderPane = new BorderPane();
        borderPane.setCenter(center);
        borderPane.setTop(menuBar);

        mainScene = new Scene(borderPane, 800,600);
        mainScene.getStylesheets().add("styles.css");
        mainWin.setScene(mainScene);
        mainWin.setResizable(false);
        mainWin.show();
    }

    private void refreshGallery(){

        gallery.getChildren().clear();

        for (int i =0 ; i < Album.getImageData().size(); i++){
            gallery.getChildren().add(Album.getImageData().get(i).getImageBtn());
        }
    }
}

专辑.java

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.image.ImageView;
import java.util.*;

/**
 * Created by Alyssa on 9/27/2015.
 */
public class Album extends Observable{
    private static List<ImageData> imageData = new ArrayList<>();

    ObservableList<ImageData> observableList = FXCollections.observableList(imageData);
    public ObservableList<ImageData> getObsList(){return observableList;}

    private BooleanProperty changed = new SimpleBooleanProperty();
    public final boolean getChanged(){return changed.get();}
    public final void setChanged(boolean value){changed.set(value);}
    public BooleanProperty changedProperty(){return changed;}

    public Album(){}

    public static List<ImageData> getImageData(){ return imageData; }

    public void addImage(String image, String title, String desc, String loc) {
        imageData.add(0, new ImageData(image, title, desc, loc));
    }

    public void removeImage(ImageView img){

        List<ImageData> toRemove = new ArrayList<>();
        for(ImageData a: imageData){
            if(a.getImageView() == img){
                toRemove.add(a);
                //observableList.remove(a);
                break;
            }
        }

        imageData.removeAll(toRemove);
        if (this.getChanged() == true)
            this.setChanged(false);
        else
            this.setChanged(true);
    }

    public void sortAlbumTitle(Album album) {
        System.out.println("Sort by Title");
        Collections.sort(album.getImageData(), new Comparator<ImageData>() {
            public int compare(ImageData img1, ImageData img2) {
                return img1.getTitle().compareToIgnoreCase(img2.getTitle());
            }
        });
    }

    public void sortAlbumDate(Album album) {
        System.out.println("Sort by Date");
        Collections.sort(album.getImageData(), new Comparator<ImageData>() {
            public int compare(ImageData img1, ImageData img2) {
                return img1.getDate().compareTo(img2.getDate());
            }
        });
    }

    public void sortAlbumLoc(Album album) {
        System.out.println("Sort by description");
        Collections.sort(album.getImageData(), new Comparator<ImageData>() {
            public int compare(ImageData img1, ImageData img2) {
                return img1.getLocation().compareToIgnoreCase(img2.getLocation());
            }
        });
    }
}

图像数据.java

import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;


/**
 * Created by Alyssa on 9/27/2015.
 */
public class ImageData extends Album implements EventHandler<MouseEvent>{

private Image image;
private ImageView smImgView;
private ImageView imgView;
private String title = null;
private String desc = null;
private Date dateAdded = null;
private Date date = null;
private String location = null;
private Button btn;



public ImageData(){};
public ImageData(String img, String nTitle, String nDesc, String loc){

    image = new Image(img);
    smImgView = new ImageView(image);   //thumbnail
    getSmImageView().setFitWidth(80);
    smImgView.setPreserveRatio(true);
    imgView = new ImageView(image); //fullsize

    //image info
    title = nTitle;
    desc=nDesc;
    location = loc;
    dateAdded = new java.util.Date();
    date = new java.util.Date();


    btn = new Button();
    btn.setGraphic(smImgView);
    btn.setOnMouseClicked(this);

}

//getters/setters
public String getTitle(){ return title; }

public void setTitle(String nTitle){ this.title = nTitle; }

public String getDesc() { return desc; }

public void setDesc(String nDesc) { this.desc = nDesc; }

public java.util.Date getDateAdded() { return dateAdded; }

public Date getDate() { return date; }

public void setDate(Date nDate) { this.date = nDate; }

public String getLocation() { return location; }

public void setLocation(String nLocation) { this.location = nLocation; }

public ImageView getSmImageView(){ return this.smImgView; }

public ImageView getImageView(){ return this.imgView; }

public String getImage(){return this.image.toString(); }

public Button getImageBtn(){return this.btn; }

@Override
public void handle(MouseEvent event) {
    ArrayList arr = DisplayEditDetail.display(imgView, title, dateAdded, date, desc, location);
    title = arr.get(0).toString();

    desc = arr.get(2).toString();
    location = arr.get(3).toString();
    if (arr.get(1) != null) {
        try {
            SimpleDateFormat dateformat = new SimpleDateFormat("MM/dd/yyyy");
            Date nDate = dateformat.parse(arr.get(1).toString());
            date = nDate;
        }
        catch (ParseException ex) {

        }

    }
    if (arr.get(4) == "True") {
        super.removeImage(imgView);
    }
}
}

DisplayEditDetail.java

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import java.util.ArrayList;

/**
 * Created by Alyssa on 9/27/2015.
 */
public class DisplayEditDetail extends Album{

private Boolean delete = false;

public static ArrayList<String> display(ImageView img, String title, Date dateAdded, Date date, String desc, String loc){

    String cdate = null, olddate = null;
    if (date != null){
        cdate = date.toString();
        DateFormat df = new SimpleDateFormat("MM/dd/YYYY");
        olddate = df.format(date);
    }

    ArrayList<String> changes = new ArrayList<>();
    changes.add(title);
    changes.add(cdate);
    changes.add(desc);
    changes.add(loc);
    changes.add("False");

    Stage window = new Stage();

    window.initModality(Modality.APPLICATION_MODAL);
    window.setTitle(title);
    window.setWidth(img.getFitWidth());

    Label dateALbl = new Label("Date Added: " + dateAdded.toString());

    Label titleLbl = new Label("Title");
    TextField titleTf = new TextField(title);
    int TITLE_MAX = 100;
    titleTf.textProperty().addListener(new ChangeListener<String>(){
        @Override
        public void changed(ObservableValue<? extends String> observable,
                            String oldValue, String newValue) {

            if(titleTf.getText().length() > TITLE_MAX ) {
                titleTf.setText(titleTf.getText().substring(0, TITLE_MAX ));
            }
        }
    });


    Label dateTLbl = new Label("Date Taken");

    TextField dateTf = new TextField(olddate);

    Label descLbl = new Label("Description");
    TextArea descTf = new TextArea(desc);
    descTf.setWrapText(true);
    descTf.setMaxWidth(250);
    descTf.setMaxHeight(100);
    int DESC_MAX = 300;
    descTf.textProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable,
                            String oldValue, String newValue) {

            if(descTf.getText().length() > DESC_MAX){
                descTf.setText(descTf.getText().substring(0, DESC_MAX));
            }
        }
    });

    Label locLbl = new Label("Location");
    TextField locTf = new TextField(loc);
    //Create two buttons

    Button confirmBtn = new Button("Save");
    Button cancelBtn = new Button("Cancel");
    Button deleteBtn = new Button("Delete");

    confirmBtn.setOnAction(e-> {
        try {
            changes.set(0, titleTf.getText());
            changes.set(1, dateTf.getText());
            if (dateTf.getText() != null) {    //throws parse exception
                SimpleDateFormat dateformat = new SimpleDateFormat("MM/dd/yyyy");
                Date nDate = dateformat.parse(dateTf.getText());
            }
            changes.set(2, descTf.getText());
            changes.set(3, locTf.getText());
            window.close();
        }
        catch(ParseException ex) {
            AlertBox.display("Invalid Date", "Error: Invalid Date Format.\n Use format MM/DD/YYYY");
            window.fireEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSE_REQUEST));
        }
    });

    cancelBtn.setOnAction(e-> {
        window.close();
    });

    deleteBtn.setOnAction(e ->{
        changes.set(4, "True");
        window.close();
    });

    window.setOnCloseRequest(e-> {
        boolean confirm = ConfirmBox.display("Exit?", "Are you sure you want to exit without saving?");
        e.consume();
        if (confirm)
            window.close();

    });

    HBox buttons = new HBox(10);
    buttons.getChildren().addAll(confirmBtn, cancelBtn, deleteBtn);
    buttons.setAlignment(Pos.CENTER);
    buttons.setPadding(new Insets(5,5,5,5));

    VBox details = new VBox(5);
    details.getChildren().addAll(dateALbl, titleLbl, titleTf, dateTLbl, dateTf, descLbl, descTf, locLbl, locTf, buttons);
    details.setAlignment(Pos.CENTER);
    details.setPadding(new Insets(5,5,5,5));

    HBox layout = new HBox(10);
    layout.getChildren().addAll(img, details);
    layout.setAlignment(Pos.CENTER);
    layout.setPadding(new Insets(10,5,10,10));
    layout.setStyle("-fx-background-color: #1d1d1d");

    Scene scene = new Scene(layout);
    scene.getStylesheets().add("styles.css");
    window.setScene(scene);
    window.showAndWait(); //must be closed before anything else

    return changes;

}

}
4

1 回答 1

0

当您从列表中删除图像时,您必须从 ObservableList 中删除表单,然后它才会调用 changeListListner。这是我的工作代码更改这些类,它将对您有用任何 ?s 评论

专辑.java

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.image.ImageView;

import java.util.*;


public class Album extends Observable{
private static ObservableList<ImageData> imageData = FXCollections.observableArrayList();

private BooleanProperty changed = new SimpleBooleanProperty();
public final boolean getChanged(){return changed.get();}
public final void setChanged(boolean value){changed.set(value);}
public BooleanProperty changedProperty(){return changed;}

public Album(){}

public static ObservableList<ImageData> getImageData(){ return imageData; }

public void addImage(String image, String title, String desc, String loc) {
    imageData.add(0, new ImageData(image, title, desc, loc));
}

public void removeImage(ImageView img){

    List<ImageData> toRemove = new ArrayList<>();
    for(ImageData a: imageData){
        if(a.getImageView() == img){
            toRemove.add(a);
            //observableList.remove(a);
            break;
        }
    }

    imageData.removeAll(toRemove);
    if (this.getChanged() == true)
        this.setChanged(false);
    else
        this.setChanged(true);
}

public void sortAlbumTitle(Album album) {
    System.out.println("Sort by Title");
    Collections.sort(album.getImageData(), new Comparator<ImageData>() {
        public int compare(ImageData img1, ImageData img2) {
            return img1.getTitle().compareToIgnoreCase(img2.getTitle());
        }
    });
}

public void sortAlbumDate(Album album) {
    System.out.println("Sort by Date");
    Collections.sort(album.getImageData(), new Comparator<ImageData>() {
        public int compare(ImageData img1, ImageData img2) {
            return img1.getDate().compareTo(img2.getDate());
        }
    });
}

public void sortAlbumLoc(Album album) {
    System.out.println("Sort by description");
    Collections.sort(album.getImageData(), new Comparator<ImageData>() {
        public int compare(ImageData img1, ImageData img2) {
            return img1.getLocation().compareToIgnoreCase(img2.getLocation());
        }
    });
}
}

源码.java

import javafx.application.Application;
import javafx.collections.ListChangeListener;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import javafx.stage.Stage;

import java.io.File;


public class Source extends Application {

protected Stage mainWin;
protected FlowPane gallery;
private static boolean delete;

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
    Album album = new Album();

    Scene mainScene;

    for (int i = 1; i < 10; i++) {
        String s = "D:\\prabhu\\w\\1";
        album.getImageData().add(
                new ImageData((s + " (" + i + ").jpg"), "cardtitle" + i,
                        "carddesc", "cardloc"));
    }

    album.getImageData().addListener(new ListChangeListener() {
        @Override
        public void onChanged(ListChangeListener.Change change) {
            refreshGallery();
        }
    });

    // FILE MENU
    Menu fileMenu = new Menu("_File");
    MenuItem addImg = new MenuItem("_Add Photo...");
    addImg.setOnAction(e -> {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Open Resource File");
        File file = fileChooser.showOpenDialog(mainWin);
        String absPath = "file:" + file.getAbsolutePath();
        absPath = absPath.replace('\\', '/');
        album.addImage(absPath, "", "", "");
        refreshGallery();
    });

    MenuItem exit = new MenuItem("_Exit");
    exit.setOnAction(e -> mainWin.close());
    fileMenu.getItems().addAll(addImg, new SeparatorMenuItem(), exit);

    // SORT MENU
    Menu sortMenu = new Menu("_Sort");
    MenuItem sortTitle = new MenuItem("_Title");
    sortTitle.setOnAction(e -> {
        album.sortAlbumTitle(album);
        refreshGallery();
    });
    MenuItem sortDate = new MenuItem("_Date Taken");
    sortDate.setOnAction(e -> {
        album.sortAlbumDate(album);
        refreshGallery();
    });
    MenuItem sortLoc = new MenuItem("_Location");
    sortLoc.setOnAction(e -> {
        album.sortAlbumLoc(album);
        refreshGallery();
    });

    sortMenu.getItems().addAll(sortTitle, sortDate, sortLoc);

    // HELP MENU
    Menu helpMenu = new Menu("_Help");
    MenuItem helpAbout = new MenuItem("_About");
    helpAbout.setOnAction(e -> Help.displayAbout());
    MenuItem helpHelp = new MenuItem("_Help");
    helpHelp.setOnAction(e -> Help.displayHelp());
    helpMenu.getItems().addAll(helpAbout, helpHelp);

    // MENU BAR
    MenuBar menuBar = new MenuBar();
    menuBar.getMenus().addAll(fileMenu, sortMenu, helpMenu);
    menuBar.setStyle("-fx-background-color: #383838;");

    mainWin = primaryStage;
    mainWin.setTitle("Photo Album");

    ScrollPane center = new ScrollPane();
    // center.setMinWidth(800);
    center.setFitToWidth(true);

    gallery = new FlowPane();
    gallery.setPadding(new Insets(5, 5, 5, 5));
    gallery.setAlignment(Pos.CENTER);
    gallery.setColumnHalignment(HPos.CENTER);
    gallery.setRowValignment(VPos.CENTER);
    gallery.setHgap(10);
    gallery.setVgap(10);
    gallery.setPrefWrapLength(785);

    for (int i = 0; i < album.getImageData().size(); i++) {
        gallery.getChildren()
                .add(album.getImageData().get(i).getImageBtn());
    }

    center.setContent(gallery);

    BorderPane borderPane = new BorderPane();
    borderPane.setCenter(center);
    borderPane.setTop(menuBar);

    mainScene = new Scene(borderPane, 800, 600);
    mainScene.getStylesheets().add("styles.css");
    mainWin.setScene(mainScene);
    mainWin.setResizable(false);
    mainWin.show();
}

private void refreshGallery() {

    gallery.getChildren().clear();

    for (int i = 0; i < Album.getImageData().size(); i++) {
        gallery.getChildren()
                .add(Album.getImageData().get(i).getImageBtn());
    }
}
}

我只修改了 3 行代码。我希望这会帮助你。和任何人发表评论

于 2015-10-06T14:34:19.400 回答