I have created my custom view and put console onto it with the help of TextConsoleViewer viewer.
It appeared on my view, but it also appeared on main console view, which is also present on layout.
How to avoid this? How to put console on my view only or, may be, it is possible to hide unneeded console on console view?
The code for view part:
public class ChatView extends ViewPart {
public static final String ID = "com.scisbo.eclipse.programw.ChatView";
private ShellMod shell;
private TextConsoleViewer textConsoleViewer;
#Override
public void createPartControl(Composite parent) {
ConsoleFinderService consoleFinderService = (ConsoleFinderService) PlatformUI.getWorkbench().getService(ConsoleFinderService.class);
MessageConsole console = consoleFinderService.findConsole("Chat");
textConsoleViewer = new TextConsoleViewer(parent, console);
shell = new ShellMod(
new PrintStream(console.newMessageStream()),
new PrintStream(console.newMessageStream())
);
}
#Override
public void setFocus() {
textConsoleViewer.getControl().setFocus();
}
}
the code for console finder service
public class ConsoleFinderService {
public MessageConsole findConsole(String name) {
ConsolePlugin plugin = ConsolePlugin.getDefault();
IConsoleManager conMan = plugin.getConsoleManager();
IConsole[] existing = conMan.getConsoles();
for (int i = 0; i < existing.length; i++)
if (name.equals(existing[i].getName()))
return (MessageConsole) existing[i];
// no console found, so create a new one
MessageConsole myConsole = new MessageConsole(name, null);
conMan.addConsoles(new IConsole[] { myConsole });
return myConsole;
}
}
Don't add the console to the console manager.
(If you do need a manager, you might want to implement a separate one.)
Related
I am often struggling with the same problem of custom Objects that creates a e.g. gui Component. And I never know what is the best way to get from the gui Component back to the object.
So multiple hacks and tricks are welcome.
Let me explain it to you:
This is my custom Object I need to find afterwards
public class MyObject {
int yearOfBirth;
String name;
public MyObject(int yearOfBirth, String name) {
this.yearOfBirth = yearOfBirth;
this.name = name;
}
public int getYearOfBirth() {
return yearOfBirth;
}
public Component getPanel() {
Component panel1 = makeTextPanel("This is the personal tab of "+name);
return panell;
}
}
This is where I need to find it through the Tab I am focusing
public class MyTabControl implements ChangeListener {
JTabbedPane myTabPane = new JTabbedPane();
public MyTabControl(){
//This will add a Listener for clicking on one Tab
myTabPane.addChangeListener(this);
}
public void oneMoreTab(MyObject myObject) {
myTabPane.addTab(myObject.name, myObject.getPanel())
}
public void stateChanged(ChangeEvent arg0) {
System.out.println("Focus of Tab changed");
int actualFocusedTabIndex = myTabPane.getSelectedIndex();
Component acutalFocusedComponent = myTabPane.getComponentAt(actualFocusedTabIndex);
//This works fine, I can get the Tab. Or at least the Component.
//But how do I get the yearOfBirth or better the Object itself?
int yearOfBirthOfTheSelectedTab = ???
}
}
This is just the main function
public static void main(String[] args) {
//Commands to start and create the GUI
MyTabControl myTabControl = new MyTabControl();
MyObject mother = new MyObject(1960, "Helen");
myTabControl.oneMoreTab(mother);
MyObject father = new MyObject(1955, "James");
myTabControl.oneMoreTab(father);
}
EDIT:
1 not working solution: Extend Component class
I have tried to extend the class Component. But this will create a failure (see comment in code):
public class ComponentWithExtras extends Component {
MyObject myObject;
public void addMyObject(MyObject myObject) {
this.myObject = myObject;
}
}
// The following line will create failure: Can't cast Component to ComponentWithExtras
ComponentWithExtras componentWithExtras = (ComponentWithExtras) myObject.getPanel();
componentWithExtras.addMyObject(myObject);
myTabPane.addTab(myObject.name, componentWithExtras);
I am working on eclipse JFace GUI stuff.
I am reading some input from the user and able to validate using the validator as below.
// creating input prompt
InputDialog inputDialog = new InputDialog(parentShell, dialogTitle, dialogMessage, initialValue, validator);
// Validator
IInputValidator validator = new IInputValidator()
{
#Override
public String isValid(String newName)
{
if (newName.isBlank())
{
return "Warning: Input is empty";
}
return null;
}
};
What I want to implement is to add a note to the user which is not related to validation.
Basically the note is about describing what happens if the button OK is pressed (As shown in image).
Any help/idea will be much appreciated.
You would have to create a new dialog class extending InputDialog to do this overriding createDialog to add extra controls. Something like:
public class InputDialogWithNote extends InputDialog
{
private Label noteLabel;
public InputDialogWithNote(final Shell parentShell, final String dialogTitle, final String dialogMessage, final String initialValue, final IInputValidator validator)
{
super(parentShell, dialogTitle, dialogMessage, initialValue, validator);
}
#Override
protected Control createDialogArea(final Composite parent)
{
Composite body = (Composite)super.createDialogArea(parent);
noteLabel = new Label(body, SWT.LEAD);
noteLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
return body;
}
}
You will have to arrange some way to set the noteLabel field.
I have looked at other similar problems on this website, however none of the solutions seem to apply to me. I have already checked the flagged answer and updated the comments, however the program is still not working.
I am trying to make a Scheduler Application. I am running into a problem with adding data into my TableView in JavaFX. This is the main program below:
public class SchedulerController implements Initializable {
/**
* Initializes the controller class.
*/
//configures the table
#FXML
private TableView<ScheduleTask> tableView;
#FXML
private TableColumn<ScheduleTask, String> timeColumn;
#FXML
private TableColumn<ScheduleTask, String> descriptionColumn;
#Override
public void initialize(URL url, ResourceBundle rb) {
// this sets up the columns in the tableview
timeColumn.setCellValueFactory(new PropertyValueFactory<ScheduleTask, String>("scheduleTime"));
descriptionColumn.setCellValueFactory(new PropertyValueFactory<ScheduleTask, String>("scheduleName"));
}
public void initData(Object[] tasks) {
TodoTask t;
//iterate around array of tasks adding to the scheduler
for (int i = 0; i < tasks.length; i++) {
t = (TodoTask) tasks[i];
t.getDueDate();
t.getNumHours();
int hoursForTask = Integer.parseInt(t.getNumHours());
String nameofScheduleTask = (t.getTodoName());
LocalDate today = LocalDate.now();
LocalDate futureDue = t.getDueDate();
double daystoDue = ChronoUnit.DAYS.between(today, futureDue);
double timeForTask = hoursForTask / daystoDue;
String timeForTaskString = Double.toString(timeForTask);
//**This is the main part where I input the data into the Scheduler, and
//nothing comes up**
ScheduleTask newScheduleTask = new ScheduleTask(t.getTodoName(),t.getNumHours());
tableView.getItems().add(newScheduleTask);
}
}
I have commented on the part where I think there is a problem. The above program is the Controller for the Scheduler Screen, and the below code links the Scheduler screen to the other screen where the data is inputted, when the user presses 'Change Screen' on my program:
public void changeScreen(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource(
"Scheduler.fxml"
));
Parent root = (Parent) loader.load();
Parent schedulerParent = FXMLLoader.load(getClass().getResource("Scheduler.fxml"));
Scene schedulerScene = new Scene(schedulerParent);
Stage window = (Stage) ((Node) event.getSource()).getScene().getWindow();
window.setScene(schedulerScene);
SchedulerController newcontroller =
loader.<SchedulerController>getController();
ObservableList ol=todoView.getItems();
Object[] ob=ol.toArray();
newcontroller.initData(todoView.getItems().toArray());
window.show();
}
I have tried to pass the objects through an array to the program above, however whenever I add a new Task and change screen to the Scheduler, there is no task added. I also already have added getters and setters in other classes, and there seem to be no problems with that. I have attached it below:
public class ScheduleTask {
private SimpleStringProperty scheduleName,scheduleTime;
public ScheduleTask(String scheduleName, String scheduleTime) {
this.scheduleName = new SimpleStringProperty (scheduleName);
this.scheduleTime = new SimpleStringProperty(scheduleTime);
}
public String getScheduleName() {
return scheduleName.get();
}
public void setScheduleName(SimpleStringProperty scheduleName) {
this.scheduleName = scheduleName;
}
public String getScheduleTime() {
return scheduleTime.get();
}
public void setScheduleTime(SimpleStringProperty scheduleTime) {
this.scheduleTime = scheduleTime;
}
}
I am not too experienced with the website, so please let me know if you need further clarification or if anything is unclear. Thank you.
When I add components to Vaadin's component (such as TabSheet or Tree) , the added components are cached. When user clicks the tab (or tree nodes) , if it contains db data , it shows stale data , not reflecting the latest db state.
I wonder if there is any way to ensure loading latest data ?
I solve the problem by defining my custom interface :
public interface Reloadable {
void reload();
}
And each component implements this Reloadable interface , such as :
#SpringComponent
public class TeachersView extends VerticalLayout implements Reloadable, Serializable {
#Inject
private TeacherDao teacherDao;
private final static int PAGESIZE = 10;
private MTable<Teacher> mTable = new MTable<>(Teacher.class);
#PostConstruct
public void init() {
// mTable settings skip here
reload();
addComponent(mTable);
}
#Override
public void reload() {
mTable.setBeans(new SortableLazyList<>(
sortablePagingProvider ,
() -> (int) teacherDao.count() ,
PAGESIZE
));
}
private SortableLazyList.SortablePagingProvider<Teacher> sortablePagingProvider =
(firstRow, asc, sortProperty) -> {
return teacherDao.findAll(
new PageRequest(
firstRow / PAGESIZE, PAGESIZE,
asc ? Sort.Direction.ASC : Sort.Direction.DESC,
sortProperty == null ? "id" : sortProperty
)
).getContent();
};
}
And this view is injected to UI class :
#SpringUI(path = "/ui")
#Theme("valo")
public class VaadinUI extends UI {
#Inject
private TeacherDao teacherDao;
#Inject
private TeachersView teachersView;
#Override
protected void init(VaadinRequest vaadinRequest) {
Panel panel = new Panel("Admin Panel");
HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
splitPanel.setSplitPosition(15, Unit.PERCENTAGE);
panel.setContent(splitPanel);
Tree tree = new Tree("Menu");
splitPanel.setFirstComponent(tree);
Label home = new Label("Home");
Map<String, Component> map = new HashMap<>();
map.put("Teachers", teachersView);
map.put("Home", home);
map.forEach((k, v) -> tree.addItem(k));
tree.addItemClickListener(event -> {
Component view = map.get(event.getItemId());
if (view instanceof Reloadable) {
((Reloadable) view).reload();
}
splitPanel.setSecondComponent(view);
});
splitPanel.setSecondComponent(home);
setContent(panel);
} // init()
}
Notice the tree.addItemClickListener , I have to check each component if it implements Reloadable , if true , invoke it.
It works . But I don't know if it the standard way achieving this ? I think it should be a common scenario , there should be something like built-in interface for Components to implement , such as onRender like that (but I cannot find one) . Did I miss anything ?
Thanks.
First of all I'm going to suggest this tutorial on Spring & Vaadin that you may have already seen, but I'll be referencing it in a few places and I think it's a good starting point for Vaadin & Spring integration.
Second, out of curiosity, why are you using a tree to build the menu?
In the example provided you seem to be modelling a navigation between some views feature, which is already available in Vaadin, and since you're using Spring, the Vaadin spring & spring-boot extensions makes it really easy to define and navigate between your views. Then you can define some specific behaviour for each view in their own enter() method. I've used the Vaadin dashboard demo as inspiration for the changes below:
#SpringView(name = TeachersView.NAME)
public class TeachersView extends VerticalLayout implements View {
public static final String NAME = "Teachers";
private Label title = new Label("Teachers view");
#PostConstruct
void init() {
addComponent(title);
}
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
// recreate or reload stuff here
title.setValue("Teachers view reloaded # " + new Date());
}
}
#SpringView(name = HomeView.NAME)
public class HomeView extends VerticalLayout implements View {
public static final String NAME = "";
#PostConstruct
void init() {
addComponent(new Label("Home"));
}
#Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
// meh, nothing special to do here
}
}
public class SpringVaadinUI extends UI {
#Autowired
private SpringViewProvider viewProvider;
#Override
protected void init(VaadinRequest vaadinRequest) {
addStyleName(ValoTheme.UI_WITH_MENU);
Panel panel = new Panel("Admin Panel");
HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
splitPanel.setSplitPosition(15, Unit.PERCENTAGE);
panel.setContent(splitPanel);
VerticalLayout navigationBar = new VerticalLayout();
navigationBar.setPrimaryStyleName(ValoTheme.MENU_ROOT);
navigationBar.addComponent(createNavigationButton("Home", FontAwesome.HOME, HomeView.NAME));
navigationBar.addComponent(createNavigationButton("Teachers", FontAwesome.GROUP, TeachersView.NAME));
splitPanel.setFirstComponent(navigationBar);
CssLayout navigationDisplay = new CssLayout();
splitPanel.setSecondComponent(navigationDisplay);
Navigator navigator = new Navigator(this, navigationDisplay);
navigator.addProvider(viewProvider);
setContent(panel);
}
private Button createNavigationButton(String caption, FontAwesome icon, final String viewName) {
Button button = new Button(caption, icon);
button.setPrimaryStyleName(ValoTheme.MENU_ITEM);
button.addStyleName(ValoTheme.BUTTON_SMALL);
button.addStyleName(ValoTheme.BUTTON_BORDERLESS);
button.addClickListener(event -> getUI().getNavigator().navigateTo(viewName));
return button;
}
}
The result is similar to:
If for some reason you can't or don't want to use the navigator, then your solution looks fine. Nonetheless, whichever solution you chose to use, you should know that by default Spring creates singletons. Except a few such as the UI, you should probably change your components to prototypes so you'll get a new instance each time. Otherwise all your users will get the same instances when accessing the application, which I don't think you want to happen.
I am creating eclipse RCP application and I am stuck with passing parameter while showing a view.
As the first approach, I tried setting a static variable in View2 from View1 and opened that view (as below). It works.
IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
String viewIdToClose = studentListView.ID;
IViewPart viewToClose = activePage.findView(viewIdToClose);
TableItem item = studentTable.getItem(studentTable.getSelectionIndex());
String text = item.getText(ListViewConstants.TABLE_COLUMN_ONE);
activePage.hideView(viewToClose);
try {
String viewIdToOpen = StudentReview.ID;
StudentReview.userId = text;
activePage.showView(viewIdToOpen);
} catch (PartInitException e) {...}
As this doesn't seem to be a good approach, I tried as per the suggestion mentioned in the below link(accepted answer).
Passing parameters to the view
. In this approach, we can pass parameters only after showing the view.
But the issue I have is, the view to be opened should have the value from selected row while calling showView() i.e, I want to populate the parameters in View 2 based on View 1's selection.
Is there any way to achieve this? Is it good to use PULL instead of PUSH approach?
Any suggestion is appreciated.
Thanks!!!
UPDATE 1:
Approach mentioned in Passing parameters to the view
Interface:
public interface ICommunicationView extends IViewPart{
public void accept(Object parameter);
}
Calling accept():
IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
String viewIdToClose = StudentListView.ID;
IViewPart viewToClose = activePage.findView(viewIdToClose);
TableItem item = studentTable.getItem(studentTable.getSelectionIndex());
String text = item.getText(ListViewConstants.TABLE_COLUMN_ONE);
activePage.hideView(viewToClose);
try {
String viewIdToOpen = StudentReview.ID;
ICommunicationView viewToOpen = (ICommunicationView) activePage.showView(viewIdToOpen);
viewToOpen.accept(text);//Sending userId to Review view
} catch (PartInitException e) { ... }
StudentReviewView:
private String studentId;
//getters and setters
#Override
public void accept(Object parameter) {
setStudentId(parameter.toString());
}
public void createPartControl(final Composite parent) {
...
System.out.println("Student Id" + this.getStudentId());
}
It prints Student Id as null.
Am I missing something obvious?
Thanks!
Here is the good links try this..
http://tomsondev.bestsolution.at/2011/02/07/enhanced-rcp-how-views-can-communicate-the-e4-way/
Platform calls createPartControl when the view is opened by activePage.showView(viewIdToOpen). So don't populate your fields on createPartControl. Do it when setStudentId is called.
I also encountered this problem. Found a way around it by repacking the specific view component that needs to be updated.
Here is a proof of concept that sets a string:
Setter interface:
public interface ViewSetter {
void setMessage(String message);
}
View that gets initialized:
//view that implements ViewSetter
#Override
public void createPartControl(Composite parent) {
label = new Label(parent, SWT.NONE); //label is a field
}
#Override
public void setMessage(final String message) {
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
label.setText(message);
label.pack(true);
}
});
}
Code that creates and initializes the view:
IViewPart view = page.showView(viewID);
ViewSetter viewSetter = (ViewSetter)view;
viewSetter.setMessage("Hello World");