(mfg, mfg);
51 | }
52 |
53 | public boolean isShowModuleName() {
54 | return showModuleName;
55 | }
56 |
57 | public void setShowModuleName(boolean showModuleName) {
58 | this.showModuleName = showModuleName;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/erlyberly/PrefBind.java:
--------------------------------------------------------------------------------
1 | /**
2 | * erlyberly, erlang trace debugger
3 | * Copyright (C) 2016 Andy Till
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package erlyberly;
19 |
20 | import java.io.File;
21 | import java.io.FileInputStream;
22 | import java.io.FileOutputStream;
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.Arrays;
26 | import java.util.List;
27 | import java.util.Map;
28 | import java.util.Timer;
29 | import java.util.TimerTask;
30 |
31 | import com.moandjiezana.toml.Toml;
32 | import com.moandjiezana.toml.TomlWriter;
33 |
34 | import erlyberly.ConnectionView.KnownNode;
35 | import javafx.beans.property.BooleanProperty;
36 | import javafx.beans.property.StringProperty;
37 | import javafx.beans.value.ObservableValue;
38 |
39 | /**
40 | * Load dot Properties files, bind them to JavaFX properties and auto-store
41 | * them when the JavaFX properties change.
42 | *
43 | * Call {@link PrefBind#setup()} before hand then {@link PrefBind#bind(String, StringProperty)} away.
44 | *
45 | * All methods must be called on the JavaFX thread.
46 | */
47 | public class PrefBind {
48 |
49 | private static final long WRITE_TO_DISK_DELAY = 500L;
50 |
51 | private static final boolean IS_DAEMON = true;
52 | private static Timer timer = new Timer(IS_DAEMON);
53 |
54 | static {
55 | timer.scheduleAtFixedRate(new TimerTask() {
56 | @Override
57 | public void run() {
58 | synchronized (AWAIT_STORE_LOCK) {
59 | if(!awaitingStore)
60 | return;
61 | awaitingStore = false;
62 | }
63 | store();
64 | }}, WRITE_TO_DISK_DELAY, WRITE_TO_DISK_DELAY);
65 | }
66 |
67 | private static Map props;
68 |
69 | private static File erlyberlyConfig;
70 |
71 | private static final Object AWAIT_STORE_LOCK = new Object();
72 | private static boolean awaitingStore;
73 |
74 | private PrefBind() {}
75 |
76 | public static void bind(final String propName, StringProperty stringProp) {
77 | if(props == null) {
78 | return;
79 | }
80 | String storedValue = (String) props.get(propName);
81 | if(storedValue != null) {
82 | stringProp.set(storedValue);
83 | }
84 | stringProp.addListener((ObservableValue extends String> o, String oldValue, String newValue) -> {
85 | set(propName, newValue);
86 | });
87 | }
88 |
89 | public static void bindBoolean(final String propName, BooleanProperty boolProp){
90 | if(props == null) {
91 | return;
92 | }
93 | Boolean storedValue = (Boolean) props.get(propName);
94 | if(storedValue != null) {
95 | boolProp.set(storedValue);
96 | }
97 | boolProp.addListener((ObservableValue extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
98 | set(propName, newValue);
99 | });
100 | }
101 |
102 | static void store() {
103 | try {
104 | //props.store(new FileOutputStream(erlyberlyConfig), " erlyberly at https://github.com/andytill/erlyberly");
105 | new TomlWriter().write(props, new FileOutputStream(erlyberlyConfig));
106 | }
107 | catch (IOException | NoClassDefFoundError e) {
108 | e.printStackTrace();
109 | }
110 | }
111 |
112 | public static void setup() throws IOException {
113 | String home = System.getProperty("user.home");
114 |
115 | File homeDir = new File(home);
116 |
117 | File dotConfigDir = new File(homeDir, ".config");
118 |
119 | if(dotConfigDir.exists()) {
120 | homeDir = dotConfigDir;
121 | }
122 |
123 | erlyberlyConfig = new File(homeDir, ".erlyberly2");
124 | erlyberlyConfig.createNewFile();
125 |
126 | Toml toml;
127 | toml = new Toml();
128 | toml.read(new FileInputStream(erlyberlyConfig));
129 | props = toml.getKeyValues();
130 | }
131 |
132 | public static Object get(Object key) {
133 | return props.get(key);
134 | }
135 |
136 | public static Object getOrDefault(String key, Object theDefault) {
137 | return props.getOrDefault(key, theDefault);
138 | }
139 |
140 | public static double getOrDefaultDouble(String key, Double theDefault) {
141 | return Double.parseDouble(PrefBind.getOrDefault(key, theDefault).toString());
142 | }
143 |
144 | public static boolean getOrDefaultBoolean(String key, boolean theDefault) {
145 | return Boolean.parseBoolean(PrefBind.getOrDefault(key, theDefault).toString());
146 | }
147 |
148 | public static void set(String propName, Object newValue) {
149 | props.put(propName, newValue);
150 | synchronized (AWAIT_STORE_LOCK) {
151 | awaitingStore = true;
152 | }
153 | }
154 |
155 | @SuppressWarnings("unchecked")
156 | public static List> getKnownNodes() {
157 | return (List>) props.getOrDefault("knownNodes", new ArrayList<>());
158 | }
159 |
160 | public static void storeKnownNode(KnownNode knownNode) {
161 | List> knownNodes = getKnownNodes();
162 | knownNodes.add(Arrays.asList(knownNode.getNodeName(), knownNode.getCookie()));
163 | props.put("knownNodes", knownNodes);
164 | store();
165 | }
166 |
167 | public static void removeKnownNode(KnownNode knownNode) {
168 | List nodeAsList = Arrays.asList(knownNode.getNodeName(), knownNode.getCookie());
169 | List> knownNodes = getKnownNodes();
170 | knownNodes.remove(nodeAsList);
171 | props.put("knownNodes", knownNodes);
172 | store();
173 | }
174 |
175 | /**
176 | * The maximum number of traces that can be queued in the trace
177 | * proccesses queue before tracing is suspended on the node.
178 | */
179 | public static int getMaxTraceQueueLengthConfig() {
180 | Number maxTraceQueueLength = (Number)getOrDefault("maxTraceQueueLength", 1000);
181 | return maxTraceQueueLength.intValue();
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/src/main/java/erlyberly/PreferencesView.java:
--------------------------------------------------------------------------------
1 | /**
2 | * erlyberly, erlang trace debugger
3 | * Copyright (C) 2016 Andy Till
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package erlyberly;
19 |
20 | import java.net.URL;
21 | import java.util.ResourceBundle;
22 |
23 | import erlyberly.format.ErlangFormatter;
24 | import erlyberly.format.ElixirFormatter;
25 | import erlyberly.format.LFEFormatter;
26 | import javafx.beans.Observable;
27 | import javafx.fxml.FXML;
28 | import javafx.fxml.Initializable;
29 | import javafx.scene.control.CheckBox;
30 | import javafx.scene.control.RadioButton;
31 | import javafx.scene.control.TextField;
32 | import javafx.scene.control.ToggleGroup;
33 |
34 | public class PreferencesView implements Initializable {
35 |
36 | @FXML
37 | private TextField nodeNameField;
38 | @FXML
39 | private TextField cookieField;
40 | @FXML
41 | private CheckBox autoConnectField;
42 | @FXML
43 | private CheckBox showSourceInSystemEditorBox;
44 | @FXML
45 | private CheckBox hideProcesses;
46 | @FXML
47 | private CheckBox hideModules;
48 | @FXML
49 | private RadioButton erlangTermsButton;
50 | @FXML
51 | private RadioButton elixirTermsButton;
52 | @FXML
53 | private RadioButton lfeTermsButton;
54 |
55 | @Override
56 | public void initialize(URL url, ResourceBundle r) {
57 | selectFormattingButton();
58 |
59 | final ToggleGroup group;
60 | group = new ToggleGroup();
61 | group.selectedToggleProperty().addListener((Observable o) -> {
62 | storeFormattingPreferenceChange();
63 | });
64 | erlangTermsButton.setToggleGroup(group);
65 | elixirTermsButton.setToggleGroup(group);
66 | lfeTermsButton.setToggleGroup(group);
67 |
68 | PrefBind.bind("targetNodeName", nodeNameField.textProperty());
69 | PrefBind.bind("cookieName", cookieField.textProperty());
70 | PrefBind.bindBoolean("autoConnect", autoConnectField.selectedProperty());
71 | PrefBind.bindBoolean("hideProcesses", hideProcesses.selectedProperty());
72 | PrefBind.bindBoolean("hideModules", hideModules.selectedProperty());
73 | PrefBind.bindBoolean("showSourceInSystemEditor", showSourceInSystemEditorBox.selectedProperty());
74 | }
75 |
76 | private void storeFormattingPreferenceChange() {
77 | if(erlangTermsButton.isSelected()) {
78 | PrefBind.set("termFormatting", "erlang");
79 | ErlyBerly.setTermFormatter(new ErlangFormatter());
80 | }
81 | else if(elixirTermsButton.isSelected()) {
82 | PrefBind.set("termFormatting", "elixir");
83 | ErlyBerly.setTermFormatter(new ElixirFormatter());
84 | }
85 | else if(lfeTermsButton.isSelected()) {
86 | PrefBind.set("termFormatting", "lfe");
87 | ErlyBerly.setTermFormatter(new LFEFormatter());
88 | }
89 | selectFormattingButton();
90 | }
91 |
92 | private void selectFormattingButton() {
93 | String formattingPref = PrefBind.getOrDefault("termFormatting", "erlang").toString();
94 | if("erlang".equals(formattingPref)) {
95 | erlangTermsButton.setSelected(true);
96 | }
97 | else if("elixir".equals(formattingPref)) {
98 | elixirTermsButton.setSelected(true);
99 | }
100 | else if("lfe".equals(formattingPref)) {
101 | lfeTermsButton.setSelected(true);
102 | }
103 | else
104 | throw new RuntimeException("Invalid configuration for property 'termFormatting' it must be 'erlang' or 'lfe' but was " + formattingPref);
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/erlyberly/ProcController.java:
--------------------------------------------------------------------------------
1 | /**
2 | * erlyberly, erlang trace debugger
3 | * Copyright (C) 2016 Andy Till
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package erlyberly;
19 |
20 | import java.io.IOException;
21 | import java.util.ArrayList;
22 | import java.util.Collections;
23 | import java.util.Comparator;
24 |
25 | import com.ericsson.otp.erlang.OtpErlangException;
26 | import com.ericsson.otp.erlang.OtpErlangObject;
27 |
28 | import erlyberly.node.RpcCallback;
29 | import javafx.application.Platform;
30 | import javafx.beans.property.SimpleBooleanProperty;
31 | import javafx.beans.property.SimpleObjectProperty;
32 | import javafx.beans.property.SimpleStringProperty;
33 | import javafx.beans.value.ObservableValue;
34 | import javafx.collections.FXCollections;
35 | import javafx.collections.ObservableList;
36 | import javafx.collections.transformation.FilteredList;
37 | import javafx.collections.transformation.SortedList;
38 | import javafx.scene.control.TableColumn.SortType;
39 |
40 | /**
41 | * Logic and processing for the entop control.
42 | */
43 | public class ProcController {
44 |
45 | private final SimpleBooleanProperty polling;
46 |
47 | private final SimpleObjectProperty procSortProperty;
48 |
49 | private ProcPollerThread procPollerThread;
50 |
51 | private final Object waiter;
52 |
53 | private int timeout = -1;
54 |
55 | private final SimpleStringProperty filter = new SimpleStringProperty();
56 |
57 | private final ObservableList processes = FXCollections.observableArrayList();
58 |
59 | private final FilteredList filteredProcesses = new FilteredList(processes);
60 |
61 | private final SortedList sortedProcesses = new SortedList(filteredProcesses);
62 |
63 | private volatile boolean temporarilySuspendPolling;
64 |
65 | public ProcController() {
66 | polling = new SimpleBooleanProperty();
67 |
68 | procSortProperty = new SimpleObjectProperty<>(new ProcSort("reduc", SortType.DESCENDING));
69 |
70 | procPollerThread = new ProcPollerThread();
71 |
72 | waiter = new Object();
73 |
74 | Platform.runLater(() -> {
75 | ErlyBerly.nodeAPI().connectedProperty().addListener((o) -> { startPollingThread(); } );
76 | });
77 |
78 | filter.addListener((o, ov, nv) -> { updateProcFilter(nv); });
79 | }
80 |
81 | public void setListComparator(ObservableValue extends Comparator super ProcInfo>> tableComparator) {
82 | sortedProcesses.comparatorProperty().bind(tableComparator);
83 | }
84 |
85 | private void updateProcFilter(String filterText) {
86 | BasicSearch basicSearch = new BasicSearch(filterText);
87 | filteredProcesses.setPredicate((proc) -> { return isMatchingProcess(basicSearch, proc); });
88 | }
89 |
90 | private boolean isMatchingProcess(BasicSearch basicSearch, ProcInfo proc) {
91 | return
92 | basicSearch.matches(proc.getPid(), proc.getProcessName());
93 | }
94 |
95 | private void startPollingThread() {
96 | if(ErlyBerly.nodeAPI().connectedProperty().get() && !procPollerThread.isAlive()) {
97 | procPollerThread.start();
98 | }
99 | }
100 |
101 | public SimpleStringProperty filterProperty() {
102 | return filter;
103 | }
104 |
105 | public void refreshOnce() {
106 | synchronized (waiter) {
107 | waiter.notify();
108 | }
109 | }
110 |
111 | public void togglePolling() {
112 | if(timeout == -1) {
113 | timeout = 1000;
114 |
115 | refreshOnce();
116 | }
117 | else {
118 | timeout = -1;
119 | }
120 | polling.set(timeout > 0);
121 | }
122 |
123 | public void clearProcesses(){
124 | processes.clear();
125 | }
126 |
127 | public ObservableList getProcs() {
128 | return sortedProcesses;
129 | }
130 |
131 | public SimpleBooleanProperty pollingProperty() {
132 | return polling;
133 | }
134 |
135 | public SimpleObjectProperty procSortProperty() {
136 | return procSortProperty;
137 | }
138 |
139 | public SimpleBooleanProperty connectedProperty() {
140 | return ErlyBerly.nodeAPI().connectedProperty();
141 | }
142 |
143 | public boolean isTemporarilySuspendPolling() {
144 | return temporarilySuspendPolling;
145 | }
146 |
147 | public void setTemporarilySuspendPolling(boolean temporarilySuspendPolling) {
148 | this.temporarilySuspendPolling = temporarilySuspendPolling;
149 | }
150 |
151 | private final class ProcPollerThread extends Thread {
152 | public ProcPollerThread() {
153 | // make sure we don't hang the VM on close because of this thread
154 | setDaemon(true);
155 | setName("Process Info Poller");
156 | }
157 |
158 | @Override
159 | public void run() {
160 |
161 | while(true) {
162 |
163 | boolean connected = ErlyBerly.nodeAPI().isConnected();
164 | if(!connected)
165 | continue;
166 |
167 | final ArrayList processList = new ArrayList<>();
168 |
169 | if (!temporarilySuspendPolling) {
170 | try {
171 | ErlyBerly.nodeAPI().retrieveProcessInfo(processList);
172 |
173 | updateProcessList(processList);
174 | }
175 | catch (Exception e) {
176 | e.printStackTrace();
177 | }
178 | }
179 |
180 | try {
181 | synchronized (waiter) {
182 | if(timeout > 0)
183 | waiter.wait(timeout);
184 | else
185 | waiter.wait();
186 | }
187 | }
188 | catch (InterruptedException e1) {
189 | e1.printStackTrace();
190 | }
191 | }
192 | }
193 |
194 | private void updateProcessList(final ArrayList processList) {
195 | Platform.runLater(new Runnable() {
196 | @Override
197 | public void run() {
198 | ProcSort procSort = procSortProperty.get();
199 | if(procSort != null) {
200 | Comparator comparator = null;
201 |
202 | if("proc".equals(procSort.getSortField())) {
203 | comparator = new Comparator() {
204 | @Override
205 | public int compare(ProcInfo o1, ProcInfo o2) {
206 | return o1.getProcessName().compareTo(o2.getProcessName());
207 | }};
208 | }
209 | else if("reduc".equals(procSort.getSortField())) {
210 | comparator = new Comparator() {
211 | @Override
212 | public int compare(ProcInfo o1, ProcInfo o2) {
213 | return Long.compare(o1.getReductions(), o2.getReductions());
214 | }};
215 | }
216 |
217 | if(comparator != null) {
218 | if(procSort.getSortType() == SortType.DESCENDING) {
219 | comparator = Collections.reverseOrder(comparator);
220 | }
221 | Collections.sort(processList, comparator);
222 | }
223 | }
224 | processes.clear();
225 | processes.addAll(processList);
226 | }});
227 | }
228 | }
229 |
230 | public void processState(ProcInfo proc, RpcCallback callback) {
231 | new ProcessStateThread(proc.getPid(), callback).start();
232 | }
233 |
234 | class ProcessStateThread extends Thread {
235 |
236 | private final String pidString;
237 | private final RpcCallback callback;
238 |
239 | public ProcessStateThread(String aPidString, RpcCallback aCallback) {
240 | pidString = aPidString;
241 | callback = aCallback;
242 |
243 | setDaemon(true);
244 | setName("Erlyberly Get Process State");
245 | }
246 |
247 | @Override
248 | public void run() {
249 | try {
250 | OtpErlangObject processState = ErlyBerly.nodeAPI().getProcessState(pidString);
251 |
252 | Platform.runLater(() -> { callback.callback(processState); });
253 | }
254 | catch (OtpErlangException | IOException e) {
255 | e.printStackTrace();
256 | }
257 | }
258 | }
259 | }
260 |
--------------------------------------------------------------------------------
/src/main/java/erlyberly/ProcInfo.java:
--------------------------------------------------------------------------------
1 | /**
2 | * erlyberly, erlang trace debugger
3 | * Copyright (C) 2016 Andy Till
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | */
18 | package erlyberly;
19 |
20 | import java.util.Map;
21 | import java.util.Objects;
22 |
23 | import com.ericsson.otp.erlang.OtpErlangAtom;
24 | import com.ericsson.otp.erlang.OtpErlangList;
25 | import com.ericsson.otp.erlang.OtpErlangLong;
26 | import com.ericsson.otp.erlang.OtpErlangString;
27 |
28 | import javafx.beans.property.LongProperty;
29 | import javafx.beans.property.SimpleLongProperty;
30 | import javafx.beans.property.SimpleStringProperty;
31 | import javafx.beans.property.StringProperty;
32 |
33 | /**
34 | * Domain object for an erlang process.
35 | */
36 | public class ProcInfo implements Comparable {
37 |
38 | private static final OtpErlangAtom TOTAL_HEAP_SIZE_ATOM = new OtpErlangAtom("total_heap_size");
39 |
40 | private static final OtpErlangAtom STACK_SIZE_ATOM = new OtpErlangAtom("stack_size");
41 |
42 | private static final OtpErlangAtom HEAP_SIZE_ATOM = new OtpErlangAtom("heap_size");
43 |
44 | private static final OtpErlangAtom MSG_QUEUE_LEN_ATOM = new OtpErlangAtom("message_queue_len");
45 |
46 | private static final OtpErlangList EMPTY_LIST = new OtpErlangList();
47 |
48 | private static final OtpErlangAtom REGISTERED_NAME_ATOM = new OtpErlangAtom("registered_name");
49 |
50 | private static final OtpErlangAtom GLOBAL_NAME_ATOM = new OtpErlangAtom("global_name");
51 |
52 | private static final OtpErlangAtom PID_ATOM = new OtpErlangAtom("pid");
53 |
54 | private static final OtpErlangAtom REDUCTIONS_ATOM = new OtpErlangAtom("reductions");
55 |
56 | private StringProperty pid;
57 |
58 | private StringProperty processName;
59 |
60 | private LongProperty reductions;
61 |
62 | private LongProperty msgQueueLen;
63 |
64 | private LongProperty heapSize;
65 |
66 | private LongProperty stackSize;
67 |
68 | private LongProperty totalHeapSize;
69 |
70 | public void setTotalHeapSize(long value) {
71 | totalHeapSizeProperty().set(value);
72 | }
73 |
74 | public long getTotalHeapSize() {
75 | return totalHeapSizeProperty().get();
76 | }
77 |
78 | public LongProperty totalHeapSizeProperty() {
79 | if (totalHeapSize == null)
80 | totalHeapSize = new SimpleLongProperty(this, "totalHeapSize");
81 | return totalHeapSize;
82 | }
83 |
84 | public void setStackSize(long value) {
85 | stackSizeProperty().set(value);
86 | }
87 |
88 | public long getStackSize() {
89 | return stackSizeProperty().get();
90 | }
91 |
92 | public LongProperty stackSizeProperty() {
93 | if (stackSize == null)
94 | stackSize = new SimpleLongProperty(this, "stackSize");
95 | return stackSize;
96 | }
97 |
98 | public void setHeapSize(long value) {
99 | heapSizeProperty().set(value);
100 | }
101 |
102 | public long getHeapSize() {
103 | return heapSizeProperty().get();
104 | }
105 |
106 | public LongProperty heapSizeProperty() {
107 | if (heapSize == null)
108 | heapSize = new SimpleLongProperty(this, "msgQueueLen");
109 | return heapSize;
110 | }
111 |
112 | public void setMsgQueueLen(long value) {
113 | msgQueueLenProperty().set(value);
114 | }
115 |
116 | public long getMsgQueueLen() {
117 | return msgQueueLenProperty().get();
118 | }
119 |
120 | public LongProperty msgQueueLenProperty() {
121 | if (msgQueueLen == null)
122 | msgQueueLen = new SimpleLongProperty(this, "msgQueueLen");
123 | return msgQueueLen;
124 | }
125 |
126 | public void setPid(String value) {
127 | pidProperty().set(value);
128 | }
129 |
130 | public String getPid() {
131 | return pidProperty().get();
132 | }
133 |
134 | public StringProperty pidProperty() {
135 | if (pid == null)
136 | pid = new SimpleStringProperty(this, "pid");
137 | return pid;
138 | }
139 |
140 | public void setProcessName(String value) {
141 | processNameProperty().set(value);
142 | }
143 |
144 | public String getProcessName() {
145 | return processNameProperty().get();
146 | }
147 |
148 | public StringProperty processNameProperty() {
149 | if (processName == null)
150 | processName = new SimpleStringProperty(this, "processName");
151 | return processName;
152 | }
153 |
154 | public void setReductions(long value) {
155 | reductionsProperty().set(value);
156 | }
157 |
158 | public long getReductions() {
159 | return reductionsProperty().get();
160 | }
161 |
162 | public LongProperty reductionsProperty() {
163 | if (reductions == null)
164 | reductions = new SimpleLongProperty(this, "reductions");
165 | return reductions;
166 | }
167 |
168 | public static ProcInfo toProcessInfo(Map