TableView with HasMap.keySet() is not dynamically updated

时间:2017-06-09 12:47:42

标签: java hashmap tableview

I want to add keys(Branch) of ObservableHashmap in column of TableView. So I created TableView with HashMap like that:

ObservableMap<Branch, Boolean> myMap = FXCollections.observableHashMap();
ObservableList<Branch> lst = FXCollections.observableArrayList(myMap.keySet());
this.chosenBranTable.setItems(lst);

... and defined CellValueFactory in this way:

this.chosenBranColumn.setCellValueFactory((CellDataFeatures<Branch, String> listItem) ->
{
    return new ReadOnlyObjectWrapper<String>(listItem.getValue().toString());
});

The problem is that - when I have changed myMap there is no changes in the TableView. But if I executed:

ObservableList<Branch> lst = FXCollections.observableArrayList(myMap.keySet());
this.chosenBranTable.setItems(lst);

after changing of myMap then changes in the TableView appeared. Before ObservableHashMap I used ObservableList and there was no problem with updating.

2 个答案:

答案 0 :(得分:0)

阅读the documentation

  

创建一个新的可观察数组列表,并向其添加集合public partial class Form1 : Form { private DataGridView dexRead; public Form1() { InitializeComponent(); //this is the Designer.cs code... dexRead = new DataGridView(); ((ISupportInitialize)(this.dexRead)).BeginInit(); SuspendLayout(); dexRead.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; dexRead.Location = new Point(12, 12); dexRead.Name = "dexRead"; dexRead.Size = new Size(606, 400); dexRead.TabIndex = 0; AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(630, 434); Controls.Add(dexRead); Name = "Form1"; Text = "Form1"; ((ISupportInitialize)(this.dexRead)).EndInit(); ResumeLayout(false); string zipTemp = (@"C:\Users\mark\Desktop\Project Dex\zipTemp\"); string machineCashCount = (""); string hostIP = ("0.0.0.0"); string userName = ("un"); string passWord = ("pw"); string remotePath = (@"/home/dex/RESPONSE/PROCESSED"); string localPath = (@"C:\Users\mark\Desktop\Project Dex\Temp\PROCESSED\"); IList<Machine> machines = new BindingList<Machine>(); dexRead.DataSource = machines; SessionOptions sessionOptions = new SessionOptions { Protocol = Protocol.Sftp, HostName = hostIP, UserName = userName, Password = passWord, PortNumber = 22, SshHostKeyFingerprint = "ssh-rsa 2048 96:48:96:52:8c:e7:de:c6:e1:00:08:7e:db:ad:e4:06" }; using (Session session = new Session()) { session.Open(sessionOptions); TransferOptions transferOptions = new TransferOptions(); transferOptions.TransferMode = TransferMode.Binary; session.GetFiles(remotePath, @"C:\Users\mark\Desktop\Project Dex\Temp\").Check(); } DirectoryInfo directorySelected = new DirectoryInfo(@"C:\Users\mark\Desktop\Project Dex\Temp\PROCESSED\"); List<string> fileNames = new List<string>(); foreach (FileInfo fileInfo in directorySelected.GetFiles("*.zip")) { fileNames.Add(fileInfo.Name); } foreach (string fileName in fileNames) { string zipFilePath = localPath + fileName; string[] timeDate = fileName.Split('_'); string Date = timeDate[1]; string Time = timeDate[2]; string[] tme = Time.Split('.'); string tm = tme[0]; string dateTime = Date + tm; DateTime dTime = DateTime.ParseExact(dateTime, "MMddyyyyHHmmss", CultureInfo.InvariantCulture); string daTime = dTime.ToString(); using (ZipFile zip1 = ZipFile.Read(zipFilePath)) { var selection = (from e in zip1.Entries where (e.FileName).StartsWith("01e") select e); Directory.CreateDirectory(zipTemp); foreach (var e in selection) { e.Extract(zipTemp, ExtractExistingFileAction.OverwriteSilently); } } DirectoryInfo dexDirect = new DirectoryInfo(@"C:\Users\mark\Desktop\Project Dex\zipTemp\"); List<string> dexName = new List<string>(); List<string> dexDate = new List<string>(); foreach (FileInfo dexInfo in dexDirect.GetFiles("*.dex")) { dexName.Add(dexInfo.Name); } foreach (string dexNames in dexName) { string dexFilePath = zipTemp + dexNames; string[] lines = System.IO.File.ReadAllLines(dexFilePath); foreach (string line in lines) { machineCashCount = Array.Find(lines, element => element.StartsWith("VA1", StringComparison.Ordinal)); } string[] MCC1 = machineCashCount.Split('*'); string[] nm = dexNames.Split('.'); int nam = int.Parse(nm[0], System.Globalization.NumberStyles.HexNumber); Console.WriteLine((nam + (":") + "Total cash count: ") + MCC1[1]); Console.WriteLine((nam + (":") + "Number of paid vends: ") + MCC1[2]); Machine m = new Machine(); m.MacNum = nam; m.CashCount = MCC1[1]; m.VendCount = MCC1[2]; m.Date_and_Time = daTime; machines.Add(m); } } } protected override void OnClosed(EventArgs e) { base.OnClosed(e); Array.ForEach(Directory.GetFiles(@"C:\Users\mark\Desktop\Project Dex\zipTemp"), File.Delete); Array.ForEach(Directory.GetFiles(@"C:\Users\mark\Desktop\Project Dex\Temp\PROCESSED"), File.Delete); } } class Machine { public int MacNum { get; set; } public string CashCount { get; set; } public string VendCount { get; set; } public string Date_and_Time { get; set; } } 的内容。

请注意,它不会通过指定的Collection创建ObservableList 支持的;它只创建一个ObservableList,其初始内容是指定Collection的元素。

即使它得到了Collection的支持,你的目标也无法实现,因为HashMap的元素没有定义的顺序。随着元素被添加到HashMap中,键的顺序可能并且很可能会发生变化。

一种有效的方法是从LinkedHashMap创建一个ObservableMap,它确实保留了它的顺序:

col

但您仍然需要手动让ObservableList响应ObservableMap中的更改:

ObservableMap<Branch, Boolean> myMap =
    FXCollections.observableMap(new LinkedHashMap<Branch, Boolean>());

答案 1 :(得分:0)

我认为您需要使用MapChangeListener

像这样:

private final MapChangeListener<K,V> mapChange;

 mapChange = new MapChangeListener<K, V>() {
            @Override
            public void onChanged(MapChangeListener.Change<? extends K, ? extends V> change) {
                // 
            }
        };

了解更多信息:https://pastebin.com/NmdTURFt