I would like to use multiple-page editor (eclipse RCP). I want to follow this tutorial
but I cannot get "plug-in with multiple page editor" when I create a new project. I have only :
Hello
with a view
with an introduction
mail template
Does anyone have an idea about how to get the option plug-in with multiple page editor when creating a new RCP project?
Thnx
PS: I use Galileo 3.5.2
Please use the Eclipse Indigo instead.
Otherwise, you can create from the empty plugin project.
Here is my example of multiple pages editor. PropertyFileEditor is multiple pages editor. Hope this will help you.
FileDocumentProvider.java
package com.bosch.training.eclipseplugin.editors;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.Properties;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.MultiPageEditorPart;
import com.bosch.training.eclipseplugin.LinkedProperties;
public class PropertyFileEditor extends MultiPageEditorPart {
public static String EDITOR_ID = "com.bosch.training.eclipseplugin.editors.PropertyFileEditor";
private Text m_keyText;
private Text m_valueText;
private TableViewer m_tableViewer;
private IPath m_filePath;
private Properties m_properties;
private FileEditor m_firstPage;
public PropertyFileEditor() {
}
#Override
protected void createPages() {
try {
m_filePath = ((FileEditorInput) getEditorInput()).getFilePath();
m_firstPage = new FileEditor();
addPage(m_firstPage, (FileEditorInput) getEditorInput());
addPage(createDesignPage());
setPagesText();
} catch (PartInitException e) {
e.printStackTrace();
}
}
private void setPagesText() {
setPageText(0, "Plain Text");
setPageText(1, "Properties");
}
#Override
public void doSave(IProgressMonitor monitor) {
m_firstPage.doSave(monitor);
}
#Override
public void doSaveAs() {
}
#Override
public boolean isSaveAsAllowed() {
return false;
}
private Control createDesignPage() {
Composite parent = new Composite(getContainer(), SWT.NONE);
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
parent.setLayout(new GridLayout(1, false));
// First row
Composite composite1 = new Composite(parent, SWT.NONE);
composite1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
composite1.setLayout(new GridLayout(3, false));
m_keyText = new Text(composite1, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
m_keyText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
m_keyText.setText("");
m_valueText = new Text(composite1, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
m_valueText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
m_valueText.setText("");
Button applyButton = new Button(composite1, SWT.PUSH);
applyButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
applyButton.setText("Apply");
applyButton.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
m_properties.put(m_keyText.getText(), m_valueText.getText());
// Update table
TableItem tableItem= new TableItem(m_tableViewer.getTable(), SWT.NONE);
tableItem.setText(new String[] { m_keyText.getText(), m_valueText.getText() });
// Update editor
IDocument doc = m_firstPage.getDocumentProvider().getDocument(getEditorInput());
int offset;
try {
offset = doc.getLineOffset(doc.getNumberOfLines() - 1);
doc.replace(offset, 0, m_keyText.getText() + "=" + m_valueText.getText() + "\n");
} catch (BadLocationException ex) {
ex.printStackTrace();
}
// set text = ""
m_keyText.setText("");
m_valueText.setText("");
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
// Second row
Composite composite2 = new Composite(parent, SWT.NONE);
composite2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
composite2.setLayout(new GridLayout(1, false));
m_tableViewer = new TableViewer(composite2, SWT.FILL);
Table table = m_tableViewer.getTable();
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
TableColumn columnKey = new TableColumn(table, SWT.LEAD);
columnKey.setText("Key");
columnKey.setWidth(300);
TableColumn columnValue = new TableColumn(table, SWT.FILL);
columnValue.setText("Value");
columnValue.setWidth(300);
table.setHeaderVisible(true);
table.setLinesVisible(true);
m_tableViewer.setContentProvider(new IStructuredContentProvider() {
#Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
#Override
public void dispose() {
}
#Override
public Object[] getElements(Object inputElement) {
return (Object[]) inputElement;
}
});
m_tableViewer.setLabelProvider(new ITableLabelProvider() {
#Override
public void removeListener(ILabelProviderListener listener) {
}
#Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
#Override
public void dispose() {
}
#Override
public void addListener(ILabelProviderListener listener) {
}
#Override
public String getColumnText(Object element, int columnIndex) {
if (element instanceof Entry) {
switch (columnIndex) {
case 0:
return String.valueOf(((Entry) element).getKey());
case 1:
return String.valueOf(((Entry) element).getValue());
}
}
return "";
}
#Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
});
m_tableViewer.setInput(loadProperties());
m_firstPage.getDocumentProvider().getDocument(getEditorInput()).addDocumentListener(new IDocumentListener() {
#Override
public void documentChanged(DocumentEvent event) {
m_tableViewer.setInput(loadProperties());
}
#Override
public void documentAboutToBeChanged(DocumentEvent event) {
}
});
return parent;
}
private Object[] loadProperties() {
IDocument document = m_firstPage.getFileDocumentProvider().getDocument(getEditorInput());
m_properties = new LinkedProperties();
ByteArrayInputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(document.get().getBytes());
m_properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
return m_properties.entrySet().toArray();
}
}
FileEditor.java
package com.bosch.training.eclipseplugin.editors;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.texteditor.ITextEditorExtension3;
public class FileEditor extends AbstractTextEditor {
public static final String EDITOR_ID = "com.bosch.training.eclipseplugin.editors.FileEditor";
private FileDocumentProvider m_fileDocumentProvider;
public FileEditor() {
setKeyBindingScopes(new String[] { "org.eclipse.ui.textEditorScope" });
internal_init();
}
protected void internal_init() {
configureInsertMode(ITextEditorExtension3.SMART_INSERT, false);
m_fileDocumentProvider = new FileDocumentProvider();
setDocumentProvider(m_fileDocumentProvider);
}
public FileDocumentProvider getFileDocumentProvider() {
return m_fileDocumentProvider;
}
}
FileEditorInput.java
package com.bosch.training.eclipseplugin.editors;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.PlatformUI;
public class FileEditorInput implements IPathEditorInput {
private IPath m_filePath;
public FileEditorInput(IPath path) {
if (path == null) {
throw new IllegalArgumentException();
}
this.m_filePath = path;
}
#Override
public int hashCode() {
return m_filePath.hashCode();
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof FileEditorInput)) {
return false;
}
FileEditorInput other = (FileEditorInput) obj;
return m_filePath.equals(other.m_filePath);
}
#Override
public boolean exists() {
return m_filePath.toFile().exists();
}
#Override
public ImageDescriptor getImageDescriptor() {
return PlatformUI.getWorkbench().getEditorRegistry().getImageDescriptor(m_filePath.toString());
}
#Override
public String getName() {
return m_filePath.toString();
}
#Override
public String getToolTipText() {
return m_filePath.makeRelative().toOSString();
}
#Override
public IPath getPath() {
return m_filePath;
}
#SuppressWarnings("rawtypes")
#Override
public Object getAdapter(Class adapter) {
return null;
}
#Override
public IPersistableElement getPersistable() {
// no persistence
return null;
}
public IPath getFilePath() {
return m_filePath;
}
public void setFilePath(IPath filePath) {
m_filePath = filePath;
}
}
PropertyFileEditor.java
package com.bosch.training.eclipseplugin.editors;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.Properties;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.MultiPageEditorPart;
import com.bosch.training.eclipseplugin.LinkedProperties;
public class PropertyFileEditor extends MultiPageEditorPart {
public static String EDITOR_ID = "com.bosch.training.eclipseplugin.editors.PropertyFileEditor";
private Text m_keyText;
private Text m_valueText;
private TableViewer m_tableViewer;
private IPath m_filePath;
private Properties m_properties;
private FileEditor m_firstPage;
public PropertyFileEditor() {
}
#Override
protected void createPages() {
try {
m_filePath = ((FileEditorInput) getEditorInput()).getFilePath();
m_firstPage = new FileEditor();
addPage(m_firstPage, (FileEditorInput) getEditorInput());
addPage(createDesignPage());
setPagesText();
} catch (PartInitException e) {
e.printStackTrace();
}
}
private void setPagesText() {
setPageText(0, "Plain Text");
setPageText(1, "Properties");
}
#Override
public void doSave(IProgressMonitor monitor) {
m_firstPage.doSave(monitor);
}
#Override
public void doSaveAs() {
}
#Override
public boolean isSaveAsAllowed() {
return false;
}
private Control createDesignPage() {
Composite parent = new Composite(getContainer(), SWT.NONE);
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
parent.setLayout(new GridLayout(1, false));
// First row
Composite composite1 = new Composite(parent, SWT.NONE);
composite1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
composite1.setLayout(new GridLayout(3, false));
m_keyText = new Text(composite1, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
m_keyText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
m_keyText.setText("");
m_valueText = new Text(composite1, SWT.SINGLE | SWT.LEAD | SWT.BORDER);
m_valueText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
m_valueText.setText("");
Button applyButton = new Button(composite1, SWT.PUSH);
applyButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
applyButton.setText("Apply");
applyButton.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
m_properties.put(m_keyText.getText(), m_valueText.getText());
// Update table
TableItem tableItem= new TableItem(m_tableViewer.getTable(), SWT.NONE);
tableItem.setText(new String[] { m_keyText.getText(), m_valueText.getText() });
// Update editor
IDocument doc = m_firstPage.getDocumentProvider().getDocument(getEditorInput());
int offset;
try {
offset = doc.getLineOffset(doc.getNumberOfLines() - 1);
doc.replace(offset, 0, m_keyText.getText() + "=" + m_valueText.getText() + "\n");
} catch (BadLocationException ex) {
ex.printStackTrace();
}
// set text = ""
m_keyText.setText("");
m_valueText.setText("");
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
// Second row
Composite composite2 = new Composite(parent, SWT.NONE);
composite2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
composite2.setLayout(new GridLayout(1, false));
m_tableViewer = new TableViewer(composite2, SWT.FILL);
Table table = m_tableViewer.getTable();
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
TableColumn columnKey = new TableColumn(table, SWT.LEAD);
columnKey.setText("Key");
columnKey.setWidth(300);
TableColumn columnValue = new TableColumn(table, SWT.FILL);
columnValue.setText("Value");
columnValue.setWidth(300);
table.setHeaderVisible(true);
table.setLinesVisible(true);
m_tableViewer.setContentProvider(new IStructuredContentProvider() {
#Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
#Override
public void dispose() {
}
#Override
public Object[] getElements(Object inputElement) {
return (Object[]) inputElement;
}
});
m_tableViewer.setLabelProvider(new ITableLabelProvider() {
#Override
public void removeListener(ILabelProviderListener listener) {
}
#Override
public boolean isLabelProperty(Object element, String property) {
return false;
}
#Override
public void dispose() {
}
#Override
public void addListener(ILabelProviderListener listener) {
}
#Override
public String getColumnText(Object element, int columnIndex) {
if (element instanceof Entry) {
switch (columnIndex) {
case 0:
return String.valueOf(((Entry) element).getKey());
case 1:
return String.valueOf(((Entry) element).getValue());
}
}
return "";
}
#Override
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
});
m_tableViewer.setInput(loadProperties());
m_firstPage.getDocumentProvider().getDocument(getEditorInput()).addDocumentListener(new IDocumentListener() {
#Override
public void documentChanged(DocumentEvent event) {
m_tableViewer.setInput(loadProperties());
}
#Override
public void documentAboutToBeChanged(DocumentEvent event) {
}
});
return parent;
}
private Object[] loadProperties() {
IDocument document = m_firstPage.getFileDocumentProvider().getDocument(getEditorInput());
m_properties = new LinkedProperties();
ByteArrayInputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(document.get().getBytes());
m_properties.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
return m_properties.entrySet().toArray();
}
}
I cannot tell you, if this template is available in Galileo. It is in Indigo.
But this template just combines two steps you can do on your own. Create an empty plugin project, open the MANIFEST.MF to open the plugin editor and select the extension tabs.
There you can add extension for editors and for wizards.
For a multipage editor click on Add, then select org.eclipse.ui.editors. In the template area at the bottom of the dialog select Multi-Page editor. Then enter the properties as show in your tutorial.
Repeat for the new wizard by selectin org.eclipse.ui.newWizard and the New File Wizard template.
Related
I tried to upload a file on firebase cloud from MainActivity, i made when application is destoryed it start background services and make a file contains StorageReference.toString()
and in background service i used getReferenceFromUrl(string)
To complete the uploading and i used after it
List<UploadTask> tasks = storage.getActiveTasks();
and i used Toast.makeText(this, "tasks: " + tasks.size(), 0).show();
and it shows tasks = 0
Why? And the upload doesnt complete yet
MainActivity
import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.ClipData;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.tasks.Task;
import com.google.android.material.appbar.AppBarLayout;
import com.google.firebase.FirebaseApp;
import com.google.firebase.storage.UploadTask;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileWriter;
import java.io.File;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public final int REQ_CD_IM = 101;
private Toolbar _toolbar;
private AppBarLayout _app_bar;
private CoordinatorLayout _coordinator;
private String image = "";
private UploadSaveed upload;
private String url = "";
private ImageView imageview1;
private Button button1;
private ProgressBar progressbar1;
private TextView textview1;
private AlertDialog.Builder d;
private Intent im = new Intent(Intent.ACTION_GET_CONTENT);
#Override
protected void onCreate(Bundle _savedInstanceState) {
super.onCreate(_savedInstanceState);
setContentView(R.layout.main);
initialize(_savedInstanceState);
upload = new UploadSaveed(getApplicationContext());
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, 1000);
} else {
initializeLogic();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1000) {
initializeLogic();
}
}
private void initialize(Bundle _savedInstanceState) {
_app_bar = findViewById(R.id._app_bar);
_coordinator = findViewById(R.id._coordinator);
_toolbar = findViewById(R.id._toolbar);
setSupportActionBar(_toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
_toolbar.setNavigationOnClickListener((view) -> {
onBackPressed();
});
imageview1 = findViewById(R.id.imageview1);
button1 = findViewById(R.id.button1);
progressbar1 = findViewById(R.id.progressbar1);
textview1 = findViewById(R.id.textview1);
d = new AlertDialog.Builder(this);
im.setType("*/*");
im.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
imageview1.setOnClickListener((view) -> {
startActivityForResult(im, REQ_CD_IM);
});
button1.setOnClickListener((view) -> {
upload.setUploadListener(new UploadSaveed.UploadSavedListener() {
#Override
public void onFailureListener(Exception e) {
SketchwareUtil.showMessage(getApplicationContext(), e.toString());
}
#Override
public void onProgressListener(UploadTask.TaskSnapshot task) {
double progress = (100 * task.getBytesTransferred()) / task.getTotalByteCount();
progressbar1.setProgress((int) progress);
double bytes = task.getBytesTransferred();
SketchwareUtil.showMessage(getApplicationContext(), "transferred : " + bytes);
if (upload.getUploadUrl() != null) {
url = upload.getUploadUrl();
}
}
#Override
public void onPausedListener(UploadTask.TaskSnapshot task) {
SketchwareUtil.showMessage(getApplicationContext(), "your uploading was paused");
}
#Override
public void onSuccessListener(UploadTask.TaskSnapshot task) {
Task<Uri> taskk = task.getStorage().getDownloadUrl();
while (!taskk.isSuccessful())
;
textview1.setText(taskk.getResult().toString());
SketchwareUtil.showMessage(getApplicationContext(), "finished");
}
});
upload.UploadFile(image);
});
}
private void initializeLogic() {
if (!isMyServiceRunning(UploadService.class)) {
} else {
stopService(new Intent(getApplicationContext(), UploadService.class));
stopService(new Intent(getApplicationContext(), UploadSaveed.class));
}
d.setTitle("AutoStart");
d.setMessage("You must enable autostart for application to Work in background.");
d.setPositiveButton("enable", (dialog, which) -> {
try {
final Intent intent = new Intent();
String manufacturer = Build.MANUFACTURER.toLowerCase();
if ("xiaomi".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.miui.securitycenter",
"com.miui.permcenter.autostart.AutoStartManagementActivity"));
} else if ("oppo".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.coloros.safecenter",
"com.coloros.safecenter.permission.startup.StartupAppListActivity"));
// intent.setComponent(new ComponentName("com.coloros.oppoguardelf",
// "com.coloros.powermanager.fuelgaue.PowerConsumptionActivity"));
} else if ("vivo".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.vivo.permissionmanager",
"com.vivo.permissionmanager.activity.BgStartUpManagerActivity"));
} else if ("huawei".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.huawei.systemmanager",
"com.huawei.systemmanager.optimize.process.ProtectActivity"));
} else if ("Letv".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.letv.android.letvsafe",
"com.letv.android.letvsafe.AutobootManageActivity"));
} else if ("Honor".equalsIgnoreCase(manufacturer)) {
intent.setComponent(new ComponentName("com.huawei.systemmanager",
"com.huawei.systemmanager.optimize.process.ProtectActivity"));
} else {
return;
}
startActivity(intent);
SketchwareUtil.showMessage(getApplicationContext(),
"please enable auto start to background application");
} catch (Exception e) {
e.printStackTrace();
}
});
d.setNegativeButton("I already enabled it", (dialog, which) -> {
});
d.create().show();
}
#Override
protected void onActivityResult(int _requestCode, int _resultCode, Intent _data) {
super.onActivityResult(_requestCode, _resultCode, _data);
switch (_requestCode) {
case REQ_CD_IM:
if (_resultCode == Activity.RESULT_OK) {
ArrayList<String> _filePath = new ArrayList<>();
if (_data != null) {
if (_data.getClipData() != null) {
for (int _index = 0; _index < _data.getClipData().getItemCount(); _index++) {
ClipData.Item _item = _data.getClipData().getItemAt(_index);
_filePath.add(FileUtil.convertUriToFilePath(getApplicationContext(), _item.getUri()));
}
} else {
_filePath.add(FileUtil.convertUriToFilePath(getApplicationContext(), _data.getData()));
}
}
image = _filePath.get((int) (0));
} else {
}
break;
default:
break;
}
}
#Override
public void onDestroy() {
super.onDestroy();
try {
File fi = new File(Environment.getExternalStorageDirectory(), "saved");
if (!fi.exists()) {
fi.mkdirs();
}
File gpxfile = new File(fi, "saved.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(url);
writer.flush();
writer.close();
} catch (IOException ee) {
ee.printStackTrace();
}
upload.PauseUploading();
startService(new Intent(this, UploadService.class));
startService(new Intent(getApplicationContext(), UploadSaveed.class));
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
UploadService
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import com.google.android.gms.tasks.Task;
import com.google.firebase.storage.UploadTask;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class UploadService extends Service {
public static final String TAG = "UploadService";
private UploadSaveed upload;
#Nullable
#Override
public IBinder onBind(Intent i) {
return null;
}
#Override
public int onStartCommand(Intent i, int flags, int startId) {
upload = new UploadSaveed(getApplicationContext());
upload.setUploadListener(new UploadSaveed.UploadSavedListener() {
#Override
public void onFailureListener(Exception e) {
simpleNotifaction(1, "Upload Faild", "Upload Faild !");
try {
File fi = new File(Environment.getExternalStorageDirectory(), "saved");
if (!fi.exists()) {
fi.mkdirs();
}
File gpxfile = new File(fi, "errors.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(e.toString());
writer.flush();
writer.close();
} catch (IOException ee) {
ee.printStackTrace();
}
}
#Override
public void onProgressListener(UploadTask.TaskSnapshot task) {
double progress = (100 * task.getBytesTransferred()) / task.getTotalByteCount();
notiProgress(1, "Uploading", "Your file is Uploading..", progress);
}
#Override
public void onPausedListener(UploadTask.TaskSnapshot task) {
SketchwareUtil.showMessage(getApplicationContext(), "your uploading is paused");
}
#Override
public void onSuccessListener(UploadTask.TaskSnapshot task) {
Task<Uri> taskk = task.getStorage().getDownloadUrl();
while (!taskk.isSuccessful())
;
simpleNotifaction(1, "Uploaded", "Url: " + taskk.getResult().toString());
stopSelf();
}
});
upload.UploadFormUrl(upload.getUploadUrl2());
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent i) {
startService(new Intent(this, UploadService.class));
super.onTaskRemoved(i);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
private void notiProgress(final double _id, final String _title, final String _text, final double _progress) {
final Context context = getApplicationContext();
android.app.NotificationManager notificationManager = (android.app.NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
androidx.core.app.NotificationCompat.Builder builder;
int notificationId = (int) _id;
String channelId = "channel-01";
String channelName = "Channel Name";
int importance = android.app.NotificationManager.IMPORTANCE_HIGH;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
android.app.NotificationChannel mChannel = new android.app.NotificationChannel(channelId, channelName,
importance);
notificationManager.createNotificationChannel(mChannel);
}
androidx.core.app.NotificationCompat.Builder mBuilder = new androidx.core.app.NotificationCompat.Builder(
context, channelId).setSmallIcon(android.R.drawable.stat_sys_upload).setTicker("")
.setContentTitle(_title).setContentText(_text).setProgress((int) 100, (int) _progress, false);
notificationManager.notify(notificationId, mBuilder.build());
}
private void simpleNotifaction(int id2, String title, String description) {
androidx.core.app.NotificationCompat.Builder builder = new androidx.core.app.NotificationCompat.Builder(this,
"channel-01")
.setSmallIcon(android.R.drawable.stat_sys_upload_done)
.setSound(android.media.RingtoneManager
.getDefaultUri(android.media.RingtoneManager.TYPE_NOTIFICATION))
.setContentTitle(title).setContentText(description)
.setPriority(androidx.core.app.NotificationCompat.PRIORITY_MAX).setAutoCancel(true);
androidx.core.app.NotificationManagerCompat notificationManager = androidx.core.app.NotificationManagerCompat
.from(this);
notificationManager.notify(id2, builder.build());
}
}
UploadSaveed
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileWriter;
import java.util.List;
import java.util.Scanner;
public class UploadSaveed extends Service {
public static final String TAG = "UploadSaveed";
private FirebaseApp app;
private StorageReference storagee, path;
private UploadTask path2;
private List<UploadTask> tasks;
private String urll;
#Nullable
#Override
public IBinder onBind(Intent i) {
return null;
}
#Override
public int onStartCommand(Intent i, int flags, int startId) {
return START_STICKY;
}
public interface UploadSavedListener {
void onProgressListener(#NonNull UploadTask.TaskSnapshot task);
void onFailureListener(#NonNull Exception e);
void onSuccessListener(#NonNull UploadTask.TaskSnapshot task);
void onPausedListener(#NonNull UploadTask.TaskSnapshot task);
}
private UploadSavedListener listener;
public void setUploadListener(UploadSavedListener listener) {
this.listener = listener;
}
public UploadSaveed() {
}
public UploadSaveed(Context c) {
FirebaseOptions options = new FirebaseOptions.Builder()
.setApplicationId("1:982483603219:android:ce7ef5f660652cdca054e6")
.setApiKey("AIzaSyAhffAnCI7dG0d3NucUAjPM6oWaX6mVSHk")
.setDatabaseUrl("trav-chat-2-default-rtdb.firebaseio.com").setStorageBucket("trav-chat-2.appspot.com")
.build();
try {
FirebaseApp.initializeApp(c, options, "firebasedb");
app = FirebaseApp.getInstance("firebasedb");
} catch (Exception e) {
e.printStackTrace();
FirebaseApp.initializeApp(c, options);
app = FirebaseApp.getInstance("firebasedb");
}
try {
File fi = new File(Environment.getExternalStorageDirectory(), "saved");
if (!fi.exists()) {
fi.mkdirs();
}
File gpxfile = new File(fi, "ssaved.txt");
FileWriter writer = new FileWriter(gpxfile);
writer.append(app.toString());
writer.flush();
writer.close();
} catch (IOException ee) {
ee.printStackTrace();
}
}
public void UploadFile(String file) {
Uri file2 = Uri.parse(file);
Uri file3 = Uri.fromFile(new File(file));
storagee = FirebaseStorage.getInstance(app).getReference();
path = storagee.child("test image").child(file2.getLastPathSegment());
path2 = path.putFile(file3);
if (listener != null) {
path2.addOnFailureListener((e) -> {
listener.onFailureListener(e);
}).addOnPausedListener((task) -> {
listener.onPausedListener(task);
}).addOnProgressListener((task) -> {
listener.onProgressListener(task);
}).addOnSuccessListener((task) -> {
listener.onSuccessListener(task);
});
} else if (listener == null) {
throw new IllegalArgumentException("listener cannot be null");
}
}
/*
public void UploadFormUrl(String url) {
storagee = FirebaseStorage.getInstance(app).getReferenceFromUrl(url);
tasks = storagee.getActiveUploadTasks();
if (tasks.size() > 0) {
if (listener != null) {
path2 = tasks.get(0);
ResumeUploading();
SketchwareUtil.showMessage(this, "lol");
path2.addOnFailureListener((e) -> {
listener.onFailureListener(e);
}).addOnPausedListener((task) -> {
listener.onPausedListener(task);
}).addOnProgressListener((task) -> {
listener.onProgressListener(task);
}).addOnSuccessListener((task) -> {
listener.onSuccessListener(task);
});
} else {
throw new IllegalArgumentException("listener cannot be null");
}
} else {
throw new IllegalArgumentException("tasks cannot be equal 0 or less");
}
}
*/
public String getUploadUrl() {
if (path != null) {
return path.toString();
} else if (storagee != null) {
return storagee.toString();
} else {
throw new IllegalArgumentException("Storage Reference is null");
}
}
public void CancelUploading() {
path2.cancel();
}
public void PauseUploading() {
path2.pause();
}
public void ResumeUploading() {
path2.resume();
}
public String getUploadUrl2() {
urll = FileUtil.readFile(Environment.getExternalStorageDirectory().toString() + "/saved/saved.txt");
return urll;
}
#Override
public void onTaskRemoved(Intent i) {
startService(new Intent(this, UploadSaveed.class));
super.onTaskRemoved(i);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
}
Try to use intent
Try this code:
val intent = Intent(this, Main2Activity::class.java)
startActivity(intent)
I have put a GWT-CellTree in a DataGrid. It works except for one thing: When clicking on the tree-expand-icon, nothing happens. I have tried to minimize the
code needed to reproduce the problem...
How can this be fixed ?
best regards, Magnus
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
public class HelloWorld implements EntryPoint {
public void onModuleLoad() {
DataGrid grid= (DataGrid) new NodesGrid().getTable();
grid.setWidth("100%");
SimpleLayoutPanel slp = new SimpleLayoutPanel();
slp.add(grid);
RootLayoutPanel.get().add(slp);
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.dom.client.Style;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.text.shared.AbstractSafeHtmlRenderer;
import com.google.gwt.text.shared.SafeHtmlRenderer;
import com.google.gwt.user.cellview.client.*;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.view.client.ListDataProvider;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
public class NodesGrid {
private AbstractCellTable<Node> table = new DataGrid<>();
private Column nameColumn;
private Column<Node, String> showBlocksColumn;
private final Set<Integer> showBlocks = new HashSet<>();
public Column getNameColumn() {
return nameColumn;
}
public AbstractCellTable<Node> getTable() {
return table;
}
public NodesGrid() {
table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
table.setWidth("100%");
CustomCellTableBuilder c = new CustomCellTableBuilder(this, table);
table.setTableBuilder(c);
Node nodes = new Node();
nodes.setName("hello");
nodes.setId(123);
Node n2 = new Node();
n2.setName("testing");
nodes.getBlocks().add(n2);
ListDataProvider<Node> dataProvider = new ListDataProvider<>();
dataProvider.addDataDisplay(table);
List<Node> list = dataProvider.getList();
list.add(nodes);
addShowBlocks();
nameColumn = getSorter(list, "Name", Comparator.comparing(Node::getName), Node::getName);
}
private Column getSorter(List<Node> list,
String name,
Comparator<Node> cmp,
Function<Node, String> supplier) {
TextColumn<Node> column = new TextColumn<Node>() {
#Override
public String getValue(Node object) {
return supplier.apply(object);
}
};
table.addColumn(column, name);
column.setSortable(true);
ColumnSortEvent.ListHandler<Node> columnSortHandler = new ColumnSortEvent.ListHandler<>(list);
columnSortHandler.setComparator(column, cmp);
table.addColumnSortHandler(columnSortHandler);
table.getColumnSortList().push(column);
return column;
}
public Column<Node, String> getShowBlocksColumn() {
return showBlocksColumn;
}
public Set<Integer> getShowBlocks() {
return showBlocks;
}
void addShowBlocks() {
SafeHtmlRenderer<String> anchorRenderer = new AbstractSafeHtmlRenderer<String>() {
#Override
public SafeHtml render(String object) {
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendHtmlConstant("(<a href=\"javascript:;\">").appendEscaped(object)
.appendHtmlConstant("</a>)");
return sb.toSafeHtml();
}
};
showBlocksColumn = new Column<Node, String>(new ClickableTextCell(anchorRenderer)) {
#Override
public String getValue(Node node) {
if (showBlocks.contains(node.getId())) {
return "hide blocks";
} else {
return "show blocks";
}
}
};
showBlocksColumn.setFieldUpdater(new FieldUpdater<Node, String>() {
#Override
public void update(int index, Node node, String value) {
if (showBlocks.contains(node.getId())) {
showBlocks.remove(node.getId());
} else {
showBlocks.add(node.getId());
}
table.redrawRow(index);
}
});
table.addColumn(showBlocksColumn);
table.setColumnWidth(0, 10, Style.Unit.EM);
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTree;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TreeNode;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.view.client.TreeViewModel;
import java.util.ArrayList;
import java.util.List;
public class NodesTree {
private CellTree tree;
public NodesTree(Node node) {
TreeViewModel model = new CustomTreeModel(node);
tree = new CellTree(model, null);
tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
TreeNode rootNode = tree.getRootTreeNode();
openAll(rootNode);
}
private static class TopLevel {
private final String name;
private List<Node> blocks = new ArrayList<>();
public TopLevel(String name) {
this.name = name;
}
public TopLevel(String name, List<Node> blocks) {
this.name = name;
this.blocks = blocks;
}
public String getName() {
return name;
}
public List<Node> getBlocks() {
return blocks;
}
}
private static class CustomTreeModel implements TreeViewModel {
private final List<TopLevel> topLevels;
private final SingleSelectionModel<String> selectionModel
= new SingleSelectionModel<>();
public CustomTreeModel(Node node) {
topLevels = new ArrayList<>();
{
TopLevel blocksNode = new TopLevel("Blocks", new ArrayList(node.getBlocks()));
topLevels.add(blocksNode);
}
{
TopLevel outgoing = new TopLevel("Outgoing");
topLevels.add(outgoing);
}
{
TopLevel incoming = new TopLevel("Incoming");
topLevels.add(incoming);
}
}
public <T> NodeInfo<?> getNodeInfo(T value) {
if (value == null) {
// LEVEL 0.
ListDataProvider<TopLevel> dataProvider
= new ListDataProvider<>(
topLevels);
Cell<TopLevel> cell = new AbstractCell<TopLevel>() {
#Override
public void render(Context context, TopLevel value, SafeHtmlBuilder sb) {
sb.appendHtmlConstant(" ");
sb.appendEscaped(value.getName());
}
};
return new DefaultNodeInfo<>(dataProvider, cell);
} else if (value instanceof TopLevel) {
// LEVEL 1.
ListDataProvider<Node> dataProvider = new ListDataProvider<>(((TopLevel) value).getBlocks());
Cell<Node> cell = new AbstractCell<Node>() {
#Override
public void render(Context context, Node value, SafeHtmlBuilder sb) {
if (value != null) {
sb.appendHtmlConstant(" ");
sb.appendEscaped("(" + value.getName() + ")");
}
}
};
return new DefaultNodeInfo<>(dataProvider, cell);
} else if (value instanceof Node) {
// LEVEL 2 - LEAF.
String params = "test";
ArrayList<String> str = new ArrayList<>();
str.add(params);
ListDataProvider<String> dataProvider = new ListDataProvider<>(str);
return new DefaultNodeInfo<>(dataProvider, new TextCell(), selectionModel, null);
}
return null;
}
public boolean isLeaf(Object value) {
if (value instanceof String) {
return true;
}
return false;
}
}
private void openAll(TreeNode rootNode) {
if (rootNode == null) return;
for (int i = 0; i < rootNode.getChildCount(); i++) {
TreeNode node = rootNode.setChildOpen(i, true);
openAll(node);
}
}
public Widget getWidget() {
return tree;
}
}
package com.raybased.gwt.configtool.client.grid;
import com.google.gwt.dom.builder.shared.DivBuilder;
import com.google.gwt.dom.builder.shared.TableCellBuilder;
import com.google.gwt.dom.builder.shared.TableRowBuilder;
import com.google.gwt.dom.client.Style;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.cellview.client.AbstractCellTable;
import com.google.gwt.user.cellview.client.AbstractCellTableBuilder;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.view.client.SelectionModel;
public class CustomCellTableBuilder extends AbstractCellTableBuilder<Node> {
NodesGrid nodesGrid;
private final String rowStyle;
private final String selectedRowStyle;
private final String cellStyle;
private final String selectedCellStyle;
/**
* Construct a new table builder.
*
* #param cellTable the table this builder will build rows for
*/
public CustomCellTableBuilder(NodesGrid nodesGrid, AbstractCellTable<Node> cellTable) {
super(cellTable);
this.nodesGrid = nodesGrid;
AbstractCellTable.Style style = cellTable.getResources().style();
rowStyle = style.evenRow();
selectedRowStyle = " " + style.selectedRow();
cellStyle = style.cell() + " " + style.evenRowCell();
selectedCellStyle = " " + style.selectedRowCell();
}
#Override
protected void buildRowImpl(Node rowValue, int absRowIndex) {
// Calculate the row styles.
SelectionModel<? super Node> selectionModel = cellTable.getSelectionModel();
boolean isSelected =
(selectionModel == null || rowValue == null) ? false : selectionModel
.isSelected(rowValue);
StringBuilder trClasses = new StringBuilder(rowStyle);
if (isSelected) {
trClasses.append(selectedRowStyle);
}
String cellStyles = cellStyle;
if (isSelected) {
cellStyles += selectedCellStyle;
}
TableRowBuilder row = startRow();
row.className(trClasses.toString());
buildRow(row, rowValue, cellStyles, nodesGrid.getShowBlocksColumn());
buildRow(row, rowValue, cellStyles, nodesGrid.getNameColumn());
row.endTR();
if (nodesGrid.getShowBlocks().contains(rowValue.getId())) {
buildBlockRow(rowValue, cellStyles);
}
}
void buildRow(TableRowBuilder row, Node rowValue, String cellStyles, Column column) {
TableCellBuilder td = row.startTD();
td.className(cellStyles);
td.style().outlineStyle(Style.OutlineStyle.NONE).endStyle();
renderCell(td, createContext(0), column, rowValue);
td.endTD();
}
private void buildBlockRow(Node rowValue, String cellStyles) {
TableRowBuilder row = startRow();
buildCell(rowValue, cellStyles, row);
row.endTR();
}
private void buildCell(Node rowValue, String cellStyles, TableRowBuilder row) {
NodesTree hw = new NodesTree(rowValue);
TableCellBuilder td = row.startTD().colSpan(5);
td.className(cellStyles);
DivBuilder div = td.startDiv();
String t = hw.getWidget().getElement().getInnerHTML();
div.html(SafeHtmlUtils.fromTrustedString(t));
div.end();
td.endTD();
}
}
package com.raybased.gwt.configtool.client.grid;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class Node implements Serializable {
String name;
List<Node> blocks = new ArrayList<>();
String params;
int id;
public Node() {
}
public String getParams() {
return params;
}
public void setParams(String params) {
this.params = params;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Node> getBlocks() {
return blocks;
}
}
I'm using an editable ListView containing Patterns.
The user can see and edit the regexs in the list, and I'd like to validate whether the regex is syntactically correct before committing the value (and give feedback like a red border to the user).
Is there a way to do so?
patternList.setCellFactory(TextFieldListCell.forListView(new StringConverter<Pattern>() {
#Override
public String toString(Pattern pattern) {
return pattern.toString();
}
#Override
public Pattern fromString(String string) {
try {
return Pattern.compile(string);
} catch (PatternSyntaxException e) {
return null;
}
}
}));
patternList.setOnEditCommit(e -> {
if (e.getNewValue() == null) {
// TODO pattern syntax error, prevent commit and stay in edit mode
} else {
patternList.getItems().set(e.getIndex(), e.getNewValue());
}
});
I would do this by creating a TableCell implementation. E.g.:
import java.util.function.Predicate;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.css.PseudoClass;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public class ValidatingEditingCell<S> extends TableCell<S, String> {
private final TextField textField ;
private static final PseudoClass INVALID = PseudoClass.getPseudoClass("invalid");
private BooleanProperty valid = new SimpleBooleanProperty();
public ValidatingEditingCell(Predicate<String> validator) {
this.textField = new TextField();
valid.bind(Bindings.createBooleanBinding(() -> textField.getText() != null && validator.test(textField.getText()),
textField.textProperty()));
valid.addListener((obs, wasValid, isValid) -> {
pseudoClassStateChanged(INVALID, ! isValid);
});
pseudoClassStateChanged(INVALID, ! valid.get());
textField.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
if (e.getCode() == KeyCode.ENTER && valid.get()) {
commitEdit(textField.getText());
}
if (e.getCode() == KeyCode.ESCAPE) {
cancelEdit();
}
});
setGraphic(textField);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setText(empty ? null : item);
textField.setText(empty ? null : item);
setContentDisplay(isEditing() ? ContentDisplay.GRAPHIC_ONLY : ContentDisplay.TEXT_ONLY);
}
#Override
public void cancelEdit() {
super.cancelEdit();
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void commitEdit(String newValue) {
super.commitEdit(newValue);
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
#Override
public void startEdit() {
super.startEdit();
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
textField.selectAll();
textField.requestFocus();
}
}
This takes a predicate as an argument; the predicate returns true for valid text and false for invalid text. It sets a CSS pseudoclass on the cell, so you can use CSS to style the text field (or cell itself, if needed).
Here's a simple example which validates three different columns differently:
import java.util.function.Function;
import java.util.function.Predicate;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ValidatingTableExample extends Application {
private static <S> TableColumn<S, String> column(String title, Function<S, StringProperty> property,
Predicate<String> validator) {
TableColumn<S, String> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
col.setCellFactory(tc -> new ValidatingEditingCell<>(validator));
col.setPrefWidth(150);
return col ;
}
#Override
public void start(Stage primaryStage) {
TableView<Address> table = new TableView<>();
table.setEditable(true);
table.getColumns().add(column("City", Address::cityProperty, s -> ! s.isEmpty()));
table.getColumns().add(column("State", Address::stateProperty, s -> s.length()==2));
table.getColumns().add(column("Zip", Address::zipProperty, s -> s.matches("\\d{5}")));
Button newAddress = new Button("Add");
newAddress.setOnAction(e -> {
table.getItems().add(new Address("City", "State", "Zip"));
});
Button debug = new Button("Debug");
debug.setOnAction(e ->
table.getItems().stream()
.map(address -> String.format("%s, %s %s", address.getCity(), address.getState(), address.getZip()))
.forEach(System.out::println));
HBox buttons = new HBox(5, newAddress, debug);
buttons.setAlignment(Pos.CENTER);
buttons.setPadding(new Insets(5));
BorderPane root = new BorderPane(table, null, null, buttons, null);
Scene scene = new Scene(root, 600, 600);
scene.getStylesheets().add(getClass().getResource("validating-cell.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static class Address {
private final StringProperty city = new SimpleStringProperty();
private final StringProperty state = new SimpleStringProperty();
private final StringProperty zip = new SimpleStringProperty();
public Address(String city, String state, String zip) {
setCity(city);
setState(state);
setZip(zip);
}
public final StringProperty cityProperty() {
return this.city;
}
public final String getCity() {
return this.cityProperty().get();
}
public final void setCity(final String city) {
this.cityProperty().set(city);
}
public final StringProperty stateProperty() {
return this.state;
}
public final String getState() {
return this.stateProperty().get();
}
public final void setState(final String state) {
this.stateProperty().set(state);
}
public final StringProperty zipProperty() {
return this.zip;
}
public final String getZip() {
return this.zipProperty().get();
}
public final void setZip(final String zip) {
this.zipProperty().set(zip);
}
}
public static void main(String[] args) {
launch(args);
}
}
and some sample CSS:
.table-cell:invalid .text-field {
-fx-focus-color: red ;
-fx-control-inner-background: #ffc0c0 ;
-fx-accent: red ;
}
I finally found a way, by overriding the commitEdit() method of TextFieldListCell:
patternList.setCellFactory(l -> new TextFieldListCell<Pattern>(new StringConverter<Pattern>() {
#Override
public String toString(Pattern pattern) {
return pattern.toString();
}
#Override
public Pattern fromString(String string) {
try {
return Pattern.compile(string);
} catch (PatternSyntaxException e) {
return null;
}
}
}) {
#Override
public void commitEdit(Pattern pattern) {
if (!isEditing()) return;
PseudoClass errorClass = PseudoClass.getPseudoClass("error");
pseudoClassStateChanged(errorClass, pattern == null);
if (pattern != null) {
super.commitEdit(pattern);
}
}
});
patternList.setOnEditCommit(e -> patternList.getItems().set(e.getIndex(), e.getNewValue()));
I have a combo box that is populated with the following ObservableList:
final ObservableList<SimplePerson> persons = FXCollections.observableArrayList(
new SimplePerson("Jacob", 1),
new SimplePerson("Isabella", 2),
new SimplePerson("Ethan", 3),
new SimplePerson("Emma", 4),
new SimplePerson("Michael", 5)
);
The combobox's selected index will be set to -1, the combobox's textbox will be populated with "Michael", and the "Michael" item in the drop down list will not be selected when I run
setValue(new SimplePerson("Michael",5))
Here is some example code (SSCCE)
import javafx.application.Application;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.IntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableView;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import javafx.util.Callback;
import javafx.scene.control.ListView;
import javafx.scene.control.ListCell;
public class ComboBoxDemo extends Application {
public class SimplePerson {
private StringProperty name;
private IntegerProperty id;
private String somethingElse;
public SimplePerson(String name, Integer id) {
setName(name);
setId(id);
}
public final void setName(String value) {
nameProperty().set(value);
}
public final void setId(Integer id) {
idProperty().set(id);
}
public String getName() {
return nameProperty().get();
}
public int getId() {
return idProperty().get();
}
public StringProperty nameProperty() {
if (name == null) {
name = new SimpleStringProperty(this, "name");
}
return name;
}
public IntegerProperty idProperty() {
if (id == null) {
id = new SimpleIntegerProperty(this, "id");
}
return id;
}
#Override
public String toString() {
return name.get();
}
}
final ObservableList<SimplePerson> persons = FXCollections.observableArrayList(
new SimplePerson("Jacob", 1),
new SimplePerson("Isabella", 2),
new SimplePerson("Ethan", 3),
new SimplePerson("Emma", 4),
new SimplePerson("Michael", 5)
);
#Override
public void start(Stage stage) throws Exception {
final ComboBox<SimplePerson> cb = new ComboBox<>();
final ComboBox<String> cb2 = new ComboBox<>();
cb.setItems(persons);
cb.setEditable(true);
cb.setConverter(new StringConverter<SimplePerson>() {
#Override
public String toString(SimplePerson p) {
if (p != null) {
System.out.println("Looking up toString " + p.getName());
return p.getName();
} else {
System.out.println("Looking up toString null");
return "";
}
}
#Override
public SimplePerson fromString(String name) {
if (cb.getValue() != null) {
((SimplePerson) cb.getValue()).setName(name);
cb.show();
System.out.println("Here I am" + ((SimplePerson) cb.getValue()).getName());
return (SimplePerson) cb.getValue();
}
System.out.println("Returning null");
return null;
}
});
stage.setScene(new Scene(cb));
stage.show();
cb.setCellFactory(new Callback<ListView<SimplePerson>, ListCell<SimplePerson>>() {
#Override
public ListCell<SimplePerson> call(ListView<SimplePerson> l) {
return new ListCell<SimplePerson>() {
#Override
protected void updateItem(SimplePerson item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
System.out.println("I'm null");
} else {
System.out.println("Go get them " + item.getName());
setText(item.getName());
}
}
};
}
});
cb.setValue(new SimplePerson("Michael", 5));
System.out.println(cb.getSelectionModel().getSelectedIndex());
System.out.println(cb.getValue().getName());
}
public static void main(String[] args) {
launch(args);
}
}
The drop down list will select the right item when the ObservableList contains Strings
ObservableList<String>
You are passing a new Object to setValue() into the ComboBox. The Michael that is displayed when the ComboBox pops up is not same as the Michael in the dropdown.
If you pass cb.setValue(new SimplePerson("xyz", 5)); then the ComboBox will show the initially selected item as xyz, where xyz is not in the List of Person.
To set the exact object, you need to fetch them from their original reference, which in your case is the ObservableList<SimplePerson> persons. To fetch Michael, we use its index :
cb.setValue(persons.get(4));
If I update a JList with a long number of html formatted items then the controls stop responding and indicators won't update. This makes sense, the event thread is busy. The title can still be set though. Why is this?
Here's some (long) code demonstrating this:
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.*;
public class JListTest extends JFrame {
class TestListModel extends AbstractListModel<String> {
private static final long serialVersionUID = JListTest.serialVersionUID;
private boolean useHtml;
private String[] formattedList = new String[] {};
public int getSize() {
return formattedList.length;
}
public String getElementAt(int index) {
return formattedList[index];
}
public void setUseHtml(boolean useHtml) {
this.useHtml = useHtml;
}
public String getNewListItem() {
if (useHtml) {
return "<html><div style='padding:2px"
+ ";background-color:#EDF5F4;color:black'><div style='padding:2px;font-weight:500;'>"
+ "Item " + (100 * Math.random())
+ "</div>"
+ "This will change!"
+ "</div></html>";
} else {
return "Item " + (100 * Math.random());
}
}
public void updateItems() {
formattedList = new String[] {"<html><h1>Loading!</h1></html>"};
fireContentsChanged(this, 0, 1);
Thread buildItems = new Thread() {
#Override
public void run() {
final String[] tempList = new String[3000];
for (int i=0; i<tempList.length; i++) {
tempList[i] = getNewListItem();
}
// Just show the string bashing's done
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
formattedList = new String[] {"<html><h1>Updating!</h1></html>"};
fireContentsChanged(TestListModel.this, 0, 1);
}
});
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update
SwingUtilities.invokeLater(new Runnable() {
public void run() {
formattedList = tempList;
fireContentsChanged(TestListModel.this, 0, formattedList.length);
}
});
}
};
buildItems.start();
}
}
protected static final long serialVersionUID = 1L;
public JListTest() {
JPanel controlPanel = new JPanel();
JButton updaterControl = new JButton("Add 3000");
final JCheckBox useHtmlControl = new JCheckBox("Use HTML");
final TestListModel model = new TestListModel();
JList<String> list = new JList<String>(model);
JScrollPane scrollPane = new JScrollPane(list);
final JLabel durationIndicator = new JLabel("0");
controlPanel.add(useHtmlControl, BorderLayout.WEST);
controlPanel.add(updaterControl, BorderLayout.EAST);
getContentPane().add(controlPanel, BorderLayout.PAGE_START);
getContentPane().add(scrollPane, BorderLayout.CENTER);
getContentPane().add(durationIndicator, BorderLayout.PAGE_END);
useHtmlControl.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
model.setUseHtml(useHtmlControl.isSelected());
}
});
useHtmlControl.setSelected(false);
updaterControl.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
model.updateItems();
}
});
Timer counter = new Timer();
counter.schedule(new TimerTask() {
#Override
public void run() {
String previousCounter = durationIndicator.getText();
String newCounter = Integer.toString(
Integer.parseInt(previousCounter) + 1);
durationIndicator.setText(newCounter);
setTitle(newCounter);
}
}, 0, 100);
}
public static void main(String args[]) {
JListTest jlt = new JListTest();
jlt.pack();
jlt.setSize(300, 300);
jlt.setVisible( true );
}
}
The answer is pretty obvious - because Window title is not a Swing component, it's OS native entity.
So changes don't have to go through Swing Event Queue, but go to XDecoratedPeer.updateWMName directly in case of Unix and to some other class in other OSes.
The more interesting question would be how to avoid that UI blocking, but I don't think that's possible with just Swing, you'll have to implement some lazy loading, or rendering in batches.