I am building an application using the VAADIN framework.
I am trying to add a panel in a view containing a VerticalSplitPanel which contains two components (a button and a label for the moment).
Pretty straight forward but I'm having big problems getting it done.
I can identify that something happens, because I see the "split-divider" show when I run it in a browser, but no components inside the split-panel.
This is how I initialize the panel for the moment.
public class M2MInventory_SubscriptionsView extends AbstractView {
private Panel panel = new Panel();
private VerticalSplitPanel vSplit = new VerticalSplitPanel();
private Button upperButton = new Button("Upper Button");
private Button lowerButton = new Button("Lower Button");
public M2MInventory_SubscriptionsView() {
panel.setContent(vSplit);
vSplit.setFirstComponent(new Button("Upper"));
vSplit.setSecondComponent(new Label("Lower"));
addComponent(panel);
}
Can anyone spot an error in my ways?
Try to set panel height first. It will work but I'm not sure why.
The default layout of Panel is VerticalLayout with undefined height. It's strange, because I thought If you insert enough components in such a layout, it will grow.
Related
I'm working on large scale program. As you can see I have one main JFrame and about 20 menu items on that. Each menu item must pop up a new window. At the beginning I have created a JLayeredPanel and then I assigned each menu item to one JPanel which is inside JFrame.Then I put 25 panel in JLayeredPanel... Default all the panels are set to invisible like:
panel1.setVisible(false);
panel2.setVisible(false);
so on
When user click on one menu item, its JPanel will be visible and rest are invisible. It looks messy and I have 5000 lines code. I used InternalFrame and TabbedPane but I'm not happy with them. I want to split my code in different JPanel classes and assign them to the main JFrame. I mean when user clicked on each menu item it will call the external JPanel and render it on the JPanel on the main JFrame. I am using design mode in netbeans and it does everything for me but the simpled structure is like this and it is not working:
public class NewJPanel extends JPanel{
//I have added buttons and etc on this panel
......
}
public class frame extends JFrame(){
JPanel panel = new JPanel();
.....
Public frame(){
frame.add(panel);
}
......
//When use click on the any button on the panel
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//this is not working
NewJPanel fi = new NewJPanel ();
panel1.add(fi);
//or I tested this way separately but it did not work
panel1.remove();
panel1 = new NewJPanel();
add(panel);
invalidate();
}
}
please give me any suggestion how I can control this program in splited classes in professional way.
remove JPanel from JFrame.getContentPane.remove(myPanel)
add a new JPanel with constants, everyhing depends of used LayoutManager and its methods implemented in API
call JFrame.(re)validate() and JFrame.repaint() as last code lines, if everything is done, these notifiers correctly repaint available area
again to use CardLayout, there isn't signoficant performance or memory issue
Please give me any suggestion how I can control this program in splited classes in proressional way.
Ok.
You should put all of your JPanels in a JTabbedPane. The JTabbedPane would be added to the JFrame.
The JFrame, JTabbedPane, and each JPanel would be constructed in a separate class.
You use Swing components, rather than extending them. The only reason you extend a Swing component is if you override one of the component methods.
You should also create model classes for each of the JPanels, as well as a model class for the application.
Read this article to see how to put a Swing GUI together.
make's code better
public class NewJPanel extends JPanel{
//I have added buttons and etc on this panel
......
}
public class frame extends JFrame(){
JPanel panel = new JPanel();
.....
Public frame(){
//frame.add(panel); you dont need call frame because extends JFrame in frame class
add(panel);
......
//When use click on the any button on the panel
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//this is not working
NewJPanel fi = new NewJPanel();
add(fi);
//or I tested this way separately but it did not work
/*panel1.remove();
panel1 = new NewJPanel();
add(panel);
invalidate();you must define panel1 before use it,like :JPanel panel1 = new JPanel();*/
}
}
I am just exploring Vaadin 7 and I'm a bit frustrated to face a wall right at the start. Experienced in Swing I was happy to find Vaadin layouts are so simple and they are just like other components (they actually are Components, according to the class hierarchy). However, I faced a problem building my first Window.
So let's say I have a CustomComponent of such composition:
VerticalLayout
|
--TextArea
|
--Button
Which in the code will look like this:
public class SOComplicatedComponent extends CustomComponent {
private VerticalLayout mainLayout;
private TextArea textArea;
private Button button;
public SOComplicatedComponent() {
buildMainLayout();
setCompositionRoot(mainLayout);
}
private VerticalLayout buildMainLayout() {
// common part: create layout
mainLayout = new VerticalLayout();
mainLayout.setWidth("100%");
mainLayout.setHeight("100%");
// top-level component properties
setWidth("100.0%");
setHeight("100.0%");
// textArea
textArea = new TextArea();
textArea.setValue("hey, this button is supposed to be under me!");
textArea.setSizeUndefined();
mainLayout.addComponent(textArea);
//button
button = new Button("Ooops");
button.setSizeUndefined();
mainLayout.addComponent(button);
return mainLayout;
}
}
Then I'm constructing a Window in a following way:
public class MyUI extends UI{
#Override
protected void init(VaadinRequest request) {
...
Window window = new Window("Help me SO", new SOComplicatedComponent());
addWindow();
}
}
As a result I get a window with the TextArea and Button overlapping. When I resize the Window, contents stretch and the Layout becaomes OK, however I thought the Window is supposed to automatically fit to the contents size, isn't it?
OK, time for a final
QUESTION
I want the Button to be under the TextArea in my Window and make the Window size automatically fit its contents. What is the most proper way of achieving that in Vaadin 7?
Thanks
In this particular instance, there is no need for a separate Window - in Vaadin 7, Windows are actually child windows of the main UI; according to your comments, you do want a floating window. That's cool - but but a UI really should have some content, even if it's empty (otherwise rendering looks a little odd).
So,
You should simply be able to do
public class MyUI extends UI {
#Override
protected void init(VaadinRequest request) {
// You need to have some content on the UI, even if it's empty - otherwise it looks odd
// Here, I'm just adding an empty layout
VerticalLayout content = new VerticalLayout();
content.setSizeFull();
setContent(content);
// Adding a child window, and centering it for kicks
Window window = new Window("Help me SO", new SOComplicatedComponent());
window.center();
addWindow(window);
}
}
The AbsoluteLayout requires that you specify the location of your components. For a simple Vertical layout (i.e. TextField above Button) you would typically use the VerticalLayout
Also, setSizeFull means "make this component take all of the space allowed by it's container" -
which gets a bit confusing when you want the parent to make the child component as big as it needs to be, and no bigger. I think you really want to use "setSizeUndefined" for the CustomComponent too. So, putting all that together should give you this:
public class SOComplicatedComponent extends CustomComponent {
private VerticalLayout mainLayout;
private TextArea textArea;
private Button button;
public SOComplicatedComponent() {
buildMainLayout();
setCompositionRoot(mainLayout);
}
private VerticalLayout buildMainLayout() {
// common part: create layout
mainLayout = new VerticalLayout();
mainLayout.setSpacing(true);
mainLayout.setMargin(true);
// top-level component properties
/* CSA : SizeUndefined means "take as much space as my content needs" */
setSizeUndefined();
// textArea
textArea = new TextArea();
textArea.setValue("hey, this button is supposed to be under me!");
textArea.setSizeUndefined();
mainLayout.addComponent(textArea);
//button
button = new Button("Ooops");
button.setSizeUndefined();
mainLayout.addComponent(button);
return mainLayout;
}
}
For me, that renders like this :
I was wondering if there is a way or a method that allows me to get the current JEditorPane being displayed. For example I have a JFrame where I can create several tabs. Whenever a tab is created a new JEditorPane object is created and the content of that pane are displayed in the tab. I've implemented a ChangeListener that currently just gets me the index of the current tab whenever I open a new one, close one or navigate between tabs. What I want to do is whenever a new tab is opened or navigated to I want to get the current JEditorPane object that resides at this tab. Is there any way in which I can achieve that?
Sorry if the question is a bit vague.
Thanks in advance.
The best way to do this would be to subclass JPanel and add your custom JPanel to the tabbed pane instead:
public class EditorPanel extends JPanel {
private JEditorPane editorPane;
// ...
public EditorPanel() {
// ...
editorPane = new JEditorPane( ... );
super.add(editorPane);
// ...
}
// ...
public JEditorPane getEditorPane() {
return editorPane;
}
}
Adding a new tab:
JTabbedPane tabbedPane = ... ;
tabbedPane.addTab(name, icon, new EditorPanel());
And then when you need to access it using the tabbed pane:
Component comp = tabbedPane.getComponentAt(i);
if (comp instanceof EditorPanel) {
JEditorPane editorPane = ((EditorPanel) comp).getEditorPane();
}
This is a better alternative to maintaining a separate list and trying to maintain it alongside the tabbed pane's indices.
I want to create a function so that i can call add JLabel's, etc inside the JScrollPanel. I am not sure what the command is in NetBeans.
I tried doing JScrollPanel -> events -> container -> componentAdded to create the code below. But nothing shows up when i add code to that function.
private void initComponents() {
scrollPanel = new javax.swing.JScrollPane();
scrollPanel.addContainerListener(new java.awt.event.ContainerAdapter() {
public void componentAdded(java.awt.event.ContainerEvent evt) {
scrollPanelComponentAdded(evt);
}
}
private void scrollPanelComponentAdded(java.awt.event.ContainerEvent evt) {
System.out.println("main");
}
Any help would be great, thanks.
I don't use Netbeans and I'm not quite sure I understand exactly what you're trying to do, but the normal case for adding components to a scroll pane is to add a panel as the scroll pane's "viewport". The scroll pane is then like a window into that panel. If the panel is too big to fit into the scroll pane, the scrollbars will appear.
Here is a snippet to show what I mean. This might be what you're looking for in your initComponents method:
JPanel panel = new JPanel();
panel.add( ... ); // Add whatever components to the panel
scrollPanel = new JScrollPane();
scrollPanel.setViewportView(panel);
A ContainerListener will only be called when a component is actually added or removed from a container. In your above code, no other components are ever added to the scroll pane.
I am currently desigining a calculator panel using Java Swing. However, it's an extreme PAIN to line up all of the buttons because they are always resizing and repositioning themseleves whenever I add a new button or change the size of a button.
Is there a type of layout or something that can "lock" the buttons in position so they are not affected when I move/resize/add other buttons?
Thanks,
Bob
Extending what Tom said...
To allow a component to become invisible yet hold its place, you can place it in a CardLayout along with an empty label and just swap which is visible.
You can create a class to do this for you as follows The main just shows an example where if you click a button it's deleted while retaining its position. I put in showComponent/hideComponent and setVisible(t/f) - depends on the style you like.
This might not exactly answer what you're looking for, but might be a useful piece for part of your application.
public class Placeholder extends JPanel {
private static final long serialVersionUID = 1L;
private CardLayout cardLayout_;
public Placeholder(JComponent component) {
cardLayout_ = new CardLayout();
setLayout(cardLayout_);
add(component, "visible"); // the component
add(new JLabel(), "hidden"); // empty label
}
public void showComponent() {
cardLayout_.show(this, "visible");
}
public void hideComponent() {
cardLayout_.show(this, "hidden");
}
public void setComponentVisible(boolean visible) {
if (visible)
showComponent();
else
hideComponent();
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setLayout(new GridLayout(2,0));
for (int n = 1; n < 10; n++) {
JButton b = new JButton(n + "");
final Placeholder placeholder = new Placeholder(b);
f.add(placeholder);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
placeholder.hideComponent();
}
});
}
f.pack();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
I suggest instead of adding and removing buttons, you change their visibility property (setVisible). Some layout manager ignore non-visible components, so you may need to add a non-opqaue (or matching background) component in the same position that follows the preferred/minimum/maximum sizes of the original component. More simple you may want to use OverlayLayout.
You could use GridBagLayout to keep them in a grid, but allow them to resize
Extending what the others said...
Instead of making the components invisible, you can also disable them...
Of course, it depends on your application and your preferences.
Beside the above mentioned layouts, there are some freely available ones, like TableLayout and the versatile MigLayout.
It probably depends on the development environment you are using.
In Netbeans you can right-click the control container (form/panel) and select from a number of layout options. 'Absolute Layout' will let you position the controls without them all being resized automatically, although it won't let you place controls on top of each other.
I suggest you to check A Visual Guide to Layout Managers. Depending on the look and functionality you want there are different layouts that could work for you. If the main problem is the resize operation (of the parent JFrame o JPanel I assume), the Spring Layout allows you to establish constraints regarding the relative place of components.