因此,在我第一次使用 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;
}
}