首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX TableView在编辑“通过按钮”时的行为异常

JavaFX TableView在编辑“通过按钮”时的行为异常
EN

Stack Overflow用户
提问于 2018-06-08 18:30:46
回答 1查看 35关注 0票数 0

我有一个TableView,可以通过按钮编辑。当按钮按下阶段进行确认和其他数据弹出。问题往往是在收集和/或确认所有数据之后(例如)。删除一行或创建新行) TableView显示双甚至三重数据条目。附在下面。这几行不能点击。不能集中注意力。我的操作系统是Ubuntu16.04,我的IDE是NetBeans8.2。

代码语言:javascript
复制
   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);
    }
}

我还使用了以下方法:

代码语言:javascript
复制
   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;
    }

非常期待能学到新的东西。问候木。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-08 18:48:37

使用TextField作为graphic来显示内容,但是将Text属性设置为null。这样,graphic就不会被删除。但是,您需要这样做,因为单元格可能变为空的:

代码语言:javascript
复制
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);
        }
    }

});
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50766528

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档