我有一个可以通过按钮编辑的TableView。按钮按下阶段确认和其他数据弹出。问题通常是在收集和/或确认所有数据(例如删除行或创建新行)之后,TableView会显示双倍甚至三倍的数据条目。附在下面。这些行无法单击。不要得到一个焦点。我的操作系统是Ubuntu 16.04,我的IDE是Netbeans 8.2。
package basicShit;
import allg.ObjectFilePersistence;
import allg.StringFilePersistence;
import allg.TTADAOException;
import allg.ThinxToAdminDAO;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.TextArea;
import javafx.scene.input.MouseEvent;
import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import javafx.util.Pair;
import java.io.File;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.*;
import java.util.function.Consumer;
public class Director extends Application
{
private static ThinxToAdminDAO<Project> projectMGMT;
private static String log = "";
private static File logFilesDir = new File("/home/storm/Projekte/LogFiles");
private static final String CONTEXTFILENAME = "Contexte";
private static File contextListDir = new File("/home/storm/Projekte/Contexte");
private static String contexteFileEnd = "cntxt";
private static final String NOTETYPEFILENAME = "NoteTyps";
private static File noteListDir = new File("/home/storm/Projekte/NoteTyps");
private static String noteTypsFileEnd = "typs";
private static ButtonsTableAndTxtArea<ProjectTableViewModel> bTATA;
private final static List<String> COLUMNNAMES = Arrays.asList
("Name", "Status", "Goal");
private final static List<String> COLUMNACCESS = Arrays.asList
("name", "status", "goal");
private static Set<String> contextChoice;
private static Set<String> noteListTyps;
private final Button btnCreate = new Button("Create");
private final Button btnSave = new Button("Save");
private final Button btnReadAndUpdate = new Button("Read/Update");
private final Button btnDelete = new Button("Delete");
private final Button btnSetDataDir = new Button("Set Data Dir");
private final Button btnStats = new Button("Statistics");
private final Button btnVSG = new Button("View Step Group");
public static <S> void logIt(Pair<S, String> p)
{
String l = p.getValue() + " " + getNowTimeString();
log= log + "\n" + l;
System.out.println(l);
}
public static String getTimeString(LocalDateTime ldt)
{
ZonedDateTime nowWithTimeZone = ZonedDateTime.of
(ldt, ZoneId.of("Europe/Berlin"));
DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime
(FormatStyle.FULL);
return dtf.format(nowWithTimeZone);
}
public static String getNowTimeString()
{
return getTimeString(LocalDateTime.now());
}
public static Consumer<String> alertWindow = (s)->
{
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Error");
alert.setContentText(s);
alert.setResizable(true);
alert.getDialogPane().setPrefWidth(s.length()*7+10);
alert.showAndWait();
};
public static boolean confirm(String question)
{
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setHeaderText("Confirmation");
alert.setContentText(question);
Optional<ButtonType> result = alert.showAndWait();
return (result.get().equals(ButtonType.OK));
}
private List<Button> getBtns()
{
List<Button> btnList = new ArrayList<>();
final EventHandler<ActionEvent> eHCreate = (event)->
{
Pair<Project, String> p = create();
if (p.getKey() != null)
{
try
{
projectMGMT.add(p.getKey());
writeToTable(p.getKey());
logIt(p);
}
catch(TTADAOException e)
{
System.out.println("Couldnt register Project!");
}
}
};
btnCreate.setOnAction(eHCreate);
btnList.add(btnCreate);
final EventHandler<ActionEvent> eHSave = (event)->
{
Pair<String, String> p;
try
{
p = save();
logIt(p);
}
catch(TTADAOException e)
{
System.out.println("Couldnt save it(All).");
}
};
btnSave.setOnAction(eHSave);
btnList.add(btnSave);
final EventHandler<ActionEvent>eHReadUpdate = (event)->
{
try
{
Project project =
projectMGMT.getThingByName(detectSelection().getName());
Pair<Stage, String> p = details(project);
logIt(p);
p.getKey().showAndWait();
bTATA.getObservableList().clear();
fillTable();
}
catch(TTADAOException e)
{
System.out.println("There is no Details.");
alertWindow.accept("Select Properly");
}
};
btnReadAndUpdate.setOnAction(eHReadUpdate);
btnList.add(btnReadAndUpdate);
final EventHandler<ActionEvent> eHDelete = (event)->
{
Pair<ProjectTableViewModel, String> p = delete();
try
{
if (p.getKey() != null)
{
projectMGMT.removeByName(p.getKey().getName());
bTATA.getObservableList().remove(p.getKey());
logIt(p);
}
}
catch(TTADAOException e)
{
System.out.println("Deleting went Wrong");
}
};
btnDelete.setOnAction(eHDelete);
btnList.add(btnDelete);
final EventHandler<ActionEvent> eHSetDataDir = (event)->
{
Pair<File, String> p = setDataDir();
ProjectMGMT pm = (ProjectMGMT)projectMGMT;
pm.setStandartDir(p.getKey());
logIt(p);
};
btnSetDataDir.setOnAction(eHSetDataDir);
btnList.add(btnSetDataDir);
btnStats.setOnAction(statistics);
btnList.add(btnStats);
btnVSG.setOnAction(viewStepGroup);
btnList.add(btnVSG);
return btnList;
}
public static void main(String... args)
{
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception
{
TextArea info = new TextArea();
info.setEditable(false);
info.setStyle("-fx-highlight-fill: lightgray; -fx-highlight-text-fill: firebrick; -fx-font-size: 12px;");
info.setWrapText(true);
primaryStage = new
ButtonsTableAndTxtArea<>
("Got it All", getBtns(), COLUMNNAMES, COLUMNACCESS, info);
projectMGMT = new ProjectMGMT();
ObjectFilePersistence<Set<String>> ofp = new ObjectFilePersistence<>();
contextChoice = ofp.loadObject(CONTEXTFILENAME,contextListDir.toString(),contexteFileEnd);
noteListTyps = ofp.loadObject(NOTETYPEFILENAME,noteListDir.toString(),noteTypsFileEnd);
bTATA = (ButtonsTableAndTxtArea)primaryStage;
bTATA.getTableView().setOnMouseClicked(clickOnTable);
projectMGMT.loadData();
fillTable();
InputSpawns.initialize();
initializeTypsAndChoices();
InputSpawns.upDateContexte(contextChoice);
InputSpawns.upDateNoteTitels(noteListTyps);
btnBindings();//Must be done after bTATA is ready
primaryStage.show();
}
public void btnBindings()
{
//Thru the bind these Buttons are only available when
//a Row in the TableView is selected!!!
btnReadAndUpdate.disableProperty().bind(bTATA.getTableView().getSelectionModel().selectedItemProperty().isNull());
btnDelete.disableProperty().bind(bTATA.getTableView().getSelectionModel().selectedItemProperty().isNull());
}
public static void initializeTypsAndChoices()
{
noteListTyps = new HashSet<>();
noteListTyps.addAll(ProjectNote.typs);
contextChoice = new HashSet<>();
contextChoice.addAll(Step.contextChoice);
}
private static void writeToTable(Project project)
{
String name = project.getName();
String status = project.getLastNxtStp().getStatus();
String goal = project.getGoal();
ProjectTableViewModel pTVM = new ProjectTableViewModel(name, status, goal);
bTATA.getObservableList().add(pTVM);
}
public static Pair<String, String> save() throws TTADAOException
{
projectMGMT.saveData();
return new Pair(null, "All Saved");
}
public static ProjectTableViewModel detectSelection()
{
return bTATA.getTableView().getSelectionModel().getSelectedItem();
}
public Pair<Stage, String> details(Project project)
{
Stage stage = new DetailStage(project, log);
String s = "Detail Stage opened for Project "+project.getName()+".";
return new Pair(stage, s);
}
public static Pair<ProjectTableViewModel, String> delete()
{
ProjectTableViewModel pTVM = detectSelection();
if(pTVM!=null)
{
String name = pTVM.getName();
boolean q = confirm("Are you sure u want to delete Project "+name+" ??");
if(q)return new Pair(pTVM, "Project: "+name+" deleted.");
else return new Pair(null, "Project Deletion aborted.");
}
else return new Pair(null, "Didnt choose a Project to Delete.");
}
public EventHandler<ActionEvent> viewStepGroup = (event)->
{
};
public Pair<File, String> setDataDir()
{
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle("Choose Data Directory");
directoryChooser.setInitialDirectory(new File("/home"));
File file = directoryChooser.showDialog(null);//Owner Window is null
Pair<File, String> re;
String s;
if(file==null)s="Data Dir Not Changed!";
else s="Data Dir set to: "+file.getAbsolutePath();
return new Pair(file, s);
}
public EventHandler<ActionEvent> statistics = (event)->
{
};
public EventHandler<MouseEvent> clickOnTable = (event)->
{
ProjectTableViewModel pTVM = detectSelection();
String prjctName="";
if(pTVM!=null)
{
try
{
//Todo: Make it colored Text txt = new Text();
prjctName = pTVM.getName();
bTATA.setInfoText(projectMGMT.getThingByName(prjctName).toString());
}
catch (TTADAOException e)
{
System.out.println("Couldnt get a Project with name "+prjctName+".");
}
}
};
public static Pair<Project,String> create()
{
Optional<Project> project = InputSpawns.projectSpawn();
if(project.isPresent())
{
return new Pair(project.get(), "Project: "+project.get().getName()+" created.");
}
else
{
System.out.println("Project creation failed.");
return new Pair(null, "Project creation failed.");
}
}
public void fillTable()
{
projectMGMT.getThingNames().forEach((name) -> {
try
{
Project p = projectMGMT.getThingByName(name);
writeToTable(p);
}
catch(TTADAOException e)
{
System.out.println("Couldnt get A Project with name "+name+".");
}
});
}
@Override
public void stop()
{
try
{
Pair<String, String> p = save();
logIt(p);
}
catch(TTADAOException e)
{
System.out.println("Couldnt save it(All).");
}
String t = getNowTimeString();
StringFilePersistence.saveString("Log File Project Action" + t, logFilesDir.toString(), log);
ObjectFilePersistence<Set<String>> ofp = new ObjectFilePersistence<>();
ofp.saveObject(CONTEXTFILENAME,contextListDir.toString(),contexteFileEnd,contextChoice);
ofp.saveObject(NOTETYPEFILENAME,noteListDir.toString(),"typs",noteListTyps);
}
}
我也使用这种方法:
public static <M> TableView<M> tableSetup(ObservableList<M> data, List<String> columns, List<String> columnAccess, int[] columnWidth)
{
TableView<M> tv = new TableView<>();
int n = columns.size();
int widthSum = 0;
TableColumn<M,String>[] tColumns = new TableColumn[n];
for(int i=0;i<n;i++)
{
tColumns[i] = new TableColumn<M, String>(columns.get(i));
final int width = columnWidth[i];
tColumns[i].setPrefWidth(columnWidth[i]);
tColumns[i].setCellValueFactory(new PropertyValueFactory<>(columnAccess.get(i)));
widthSum = widthSum+ columnWidth[i];
tv.getColumns().add(tColumns[i]);
tColumns[i].setCellFactory(column->
{
return new TableCell<M, String>()
{
@Override
protected void updateItem(String item, boolean empty)
{
super.updateItem(item, empty);
if (item == null || empty)
{
setText(null);
setStyle("");
}
else
{
Text txt = new Text(item);
txt.setWrappingWidth(width-7);
setGraphic(txt);
}
}
};
});
}
tv.setPrefWidth(widthSum);
tv.setItems(data);
return tv;
}
thanx我期待着学到新的东西。 关于xylo。
答案 0 :(得分:1)
您使用TextField
graphic
作为TableCell
来显示内容,但您将Text
属性设置为null
。这样,graphic
永远不会被删除。你需要这样做,因为单元格可能变空了:
tColumns[i].setCellFactory(column -> new TableCell<M, String>() {
private final Text txt = new Text();
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty){
setGraphic(null);
} else {
txt.setText(item);
txt.setWrappingWidth(width-7);
setGraphic(txt);
}
}
});