Miglayout aligning components to top of cell - miglayout

I have a group of buttons that will just stay in the middle of the panel. I am trying to place them at the top of the panel in a flowy layout constraint. Any help in achieving this is greatly appreciated. I have tried dock and align but didn't do anything.
private class ProductPanel extends JPanel {
private JLabel lblProd;
private JButton butAdd;
private JButton butRemove;
private JButton butEdit;
private Product_Table_Model ptm;
private JScrollPane scroll;
private JPanel buttonPanel;
private JTable table;
ProductPanel() {
setLayout(new MigLayout("debug"));
ptm = new Product_Table_Model(
(ArrayList<Product>) client
.receiveObject("Get_Product_Data"));
initComponents();
}
public void initComponents() {
lblProd = new JLabel ("Product List: ");
buttonPanel = new JPanel (new MigLayout());
butAdd = new JButton ("Add");
butRemove = new JButton ("Remove");
butEdit = new JButton ("Edit");
buttonPanel.add(butAdd, "cell 0 0");
buttonPanel.add(butRemove, "cell 0 1");
buttonPanel.add(butEdit, "cell 0 2");
butAdd.setPreferredSize(new Dimension(40, 50));
add(lblProd, "wrap");
table = new JTable(ptm);
table.setFillsViewportHeight(true);
scroll = new JScrollPane(table);
add(scroll);
add(buttonPanel);
}
}

The buttons are aligned to the top, as expected. It is the panel itself that
was not aligned within its cell. So the following will fix the issue:
add(buttonPanel, "top");
You should not be setting the preffered size with a setPrefferedSize() method.
Instead, use size groups.
MigLayout is very powerful layout manager, you don't need to create two
panels with two layout managers. It is possible to create your layout much easier.
The following example is one such solution:
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import net.miginfocom.swing.MigLayout;
public class ProductPanel2 extends JPanel {
private JLabel lblProd;
private JButton butAdd;
private JButton butRemove;
private JButton butEdit;
private JScrollPane scroll;
private JTable table;
public ProductPanel2() {
initComponents();
}
private void initComponents() {
setLayout(new MigLayout());
lblProd = new JLabel("Product List: ");
butAdd = new JButton("Add");
butRemove = new JButton("Remove");
butEdit = new JButton("Edit");
table = new JTable();
table.setFillsViewportHeight(true);
scroll = new JScrollPane(table);
add(lblProd, "wrap");
add(scroll);
add(butAdd, "split 3, flowy, top, sgx");
add(butRemove, "sgx");
add(butEdit, "sgx");
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
ProductPanel2 pane = new ProductPanel2();
frame.setContentPane(pane);
frame.setSize(350, 250);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
The cell next to the table is split into three subcells. Three buttons are
inserted into these subcells. A vertical flow mode is set with the flowy
constraint. The top constraint aligns the buttons to the top. Finally, the
sgx constraint makes the button the same size.

Related

Modify a JLabel inside a void method

Please i need your help, im trying to do that i want 3-4 days now and i cant.
I have 2 Classes MainForm and Class2.
I have a JLablel inside a method at Class1 and i want to modify it by pressing a button from the Class2.
public class MainForm {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainForm window = new MainForm();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MainForm() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(400, 200, 488, 322);
frame.setTitle("ShutDown");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
frame.setResizable(false);
/**
* Time BOX
*/
JComboBox<String> timeBox = new JComboBox<String>();
timeBox.setBounds(73, 142, 90, 20);
timeBox.addItem("Days");
timeBox.addItem("Hours");
timeBox.addItem("Minutes");
timeBox.addItem("Seconds");
timeBox.addItem("Right now");
timeBox.setSelectedItem("Minutes");
frame.getContentPane().add(timeBox);
String getTimeBox = timeBox.getSelectedItem().toString();
/**
* The label info.
*/
JLabel labelInfo = new JLabel("");
labelInfo.setBounds(73, 209, 310, 14);
frame.getContentPane().add(labelInfo);
labelInfo.setText(getTimeBox);
}
and the Class 2
Class2
JButton okButton = new JButton("OK");
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
}
i tried much and allways doesnt work, whats the code i need to write in that button to get the selectedItem from the timeBox (comboBox)
and put it to that label?
First of all you need references of both
JComboBox & JLable objects in class 2.
Simple way to do that is to declare respective private members in MainForm instead of local members of initialize method & pass them in to the constructor or use setter method approach.
Let consider that the reference names are jComboBox & jLable respectively.
Now you can use following syntax to reference them from actionPerformed method of the anonymous class using this syntax Class2.this.jComboBox & Class2.this.jLable (jComboBox & jLable is object reference).

JavaFX 8: Checkbox in TableView and Add-on into to selected Item?

I would like to create a payroll program such that when the user tick a CheckBox in TableView, the name (String) will be carried on to the panel on the right and with TextFields to enter more info such as this:
I tried to follow the MVC hierarchy thus far as I code:
PayrollMainApp.java
public class PayrollMainApp extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private ObservableList<Employee> selectEmployeeTable = FXCollections.observableArrayList();
public PayrollMainApp(){
selectEmployeeTable.add(new Employee(false,"Hans Muster"));
selectEmployeeTable.add(new Employee(true,"Ruth Mueller"));
selectEmployeeTable.add(new Employee(false,"Heinz Kurz"));
selectEmployeeTable.add(new Employee(false,"Cornelia Meier"));
selectEmployeeTable.add(new Employee(false,"Werner Meyer"));
selectEmployeeTable.add(new Employee(false,"Lydia Kunz"));
selectEmployeeTable.add(new Employee(false,"Anna Best"));
selectEmployeeTable.add(new Employee(false,"Stefan Meier"));
selectEmployeeTable.add(new Employee(false,"Martin Mueller"));
}
public ObservableList<Employee> getSelectEmployeeTable(){
return selectEmployeeTable;
}
#Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("PayrollApp");
initRootLayout();
showEmployeeOverview();
}
/**
* Initializes the root layout.
*/
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(PayrollMainApp.class.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Shows the person overview inside the root layout.
*/
public void showEmployeeOverview() {
try {
// Load person overview.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(PayrollMainApp.class.getResource("view/EmployeeOverview.fxml"));
AnchorPane personOverview = (AnchorPane) loader.load();
// Set person overview into the center of root layout.
rootLayout.setCenter(personOverview);
// Give the controller access to the main app
EmployeeOverviewController controller = loader.getController();
controller.setMainApp(this);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns the main stage.
* #return
*/
public Stage getPrimaryStage() {
return primaryStage;
}
public static void main(String[] args) {
launch(args);
}
}
Employee.java
public class Employee {
private BooleanProperty checkedBox = new SimpleBooleanProperty(false);
private StringProperty employeeName = new SimpleStringProperty();
public Employee(){
super();
}
public Employee(boolean checkedBox, String employeeName){
this.checkedBox = new SimpleBooleanProperty(false);
this.employeeName = new SimpleStringProperty(employeeName);
}
public BooleanProperty checkedBoxProperty(){
return this.checkedBox;
}
public StringProperty employeeNameProperty(){
return this.employeeName;
}
public java.lang.Boolean getSelectBox() {
return this.checkedBoxProperty().get();
}
public StringProperty getEmployeeName() {
return employeeName;
}
public void setSelectBox(final java.lang.Boolean checkedBox){
this.checkedBoxProperty().set(checkedBox);
}
public void setEmployeeName(StringProperty employeeName) {
this.employeeName = employeeName;
}
}
EmployeeOverviewController.java
public class EmployeeOverviewController {
#FXML
private TableView<Employee> selectEmployeeTable;
#FXML
private TableColumn<Employee, String> employeeNameColumn;
#FXML
private TableColumn<Employee, Boolean> checkBoxColumn;
private PayrollMainApp mainApp;
public EmployeeOverviewController() {
}
#FXML
public void initialize() {
checkBoxColumn.setCellValueFactory(cellData -> cellData.getValue().checkedBoxProperty());
checkBoxColumn.setCellFactory(param -> new CheckBoxTableCell<Employee, Boolean>());
employeeNameColumn.setCellValueFactory(cellData -> cellData.getValue().employeeNameProperty());
}
public void setMainApp(PayrollMainApp mainApp){
this.mainApp = mainApp;
//Add observable list data to the table
selectEmployeeTable.setItems(mainApp.getSelectEmployeeTable());
}
}
And a util class to make the checkBox visible in the table:
SelectBoxCellFactory.java
public class SelectBoxCellFactory implements Callback {
#Override
public TableCell call(Object param) {
CheckBoxTableCell<Employee,Boolean> checkBoxCell = new CheckBoxTableCell();
return checkBoxCell;
}
}
Here is my output thus far:
I know this has a table in it as compared to the previous output. Honestly I'm still indecisive as to use which, because I think using TextFields would make it look better. But all I hope for now is that this design is not impossible to code...
I really hope you can help me... Thank you for your help in advance.
It's probably easiest to use a TableView for the right panel. You can create a FilteredList from your original list:
FilteredList<Employee> selectedEmployees
= new FilteredList<>(selectEmployeeTable, Employee::getSelectBox);
and then use that for your second table.
If you prefer to use text fields (in what looks like a GridPane?) you can still use the filtered list above, but you will need to register a listener with it and update the layout "by hand" when items are added and removed.

JavaFX 8: ComboBox button cell update behavior

I have a combo box which contains items of type Dog. If all items are replaced with new ones (via setAll on the ObservableList model) , the item renderer can cope with this update, while the button cell renderer cannot:
Here's a minimal example to reproduce the problem (full source incl. imports on GitHub):
public class ComboBoxRefresh extends Application {
private static final class Dog {
private final String name;
public Dog(String name) {
this.name = name;
}
}
private static final class DogListCell extends ListCell<Dog> {
#Override
public void updateItem(Dog item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText("");
} else {
setText(item.name);
}
}
}
private static List<Dog> createThreeDogs() {
return range(0, 3).mapToObj(i -> new Dog("Buddy " + i)).collect(toList());
}
#Override
public void start(Stage stage) throws Exception {
ObservableList<Dog> items = observableArrayList(createThreeDogs());
ComboBox<Dog> comboBox = new ComboBox<>(items);
comboBox.setPrefWidth(400);
comboBox.setCellFactory(listView -> new DogListCell());
comboBox.setButtonCell(new DogListCell());
Button button = new Button("Refresh");
button.setOnAction(event -> {
List<Dog> newItems = createThreeDogs();
items.setAll(newItems);
});
VBox box = new VBox(10, comboBox, button);
box.setPadding(new Insets(10));
Scene scene = new Scene(box);
stage.setScene(scene);
stage.show();
}
}
If I add an equals implementation to the Dog class, everything works, but this is not an option in my real application.
Are there any work-arounds to enforce a proper refresh of the button cell?
It seems to be a bug. Workaround could be
button.setOnAction( event -> {
List<Dog> newItems = createThreeDogs();
items.clear();
items.addAll(newItems);
} );

Change length of JTextPane array

I want to create an array of JTextPane that it's size and values change through out the execution of my program, such as arrayList.
Is it possible to do it similar to an arrayList?
I've two JFrames. In the first frame I have a JList with about 100 items.
After selecting any of the items I want to paste them per Drag&Drop to the second frame.
The second frame has a GridBagLayout, hence I want to paste each selected item to an
array of JTextPane after dropping the items.
I want to use JTextPane because I want to format the selected text.
now I found a solution and my code seems to work:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class RefreshPanel {
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private JTextPane [] textPane;
private JScrollPane scrollbar;
private ArrayList arrayList = new ArrayList();
private JButton newItem = new JButton("new");
private int counter=0;
private GridBagLayout gbl = new GridBagLayout();
RefreshPanel() {
panel.setBackground(Color.WHITE);
panel.setLayout(gbl);
panel.setPreferredSize(new Dimension(100,50));
scrollbar = new JScrollPane(panel);
addButtonListener();
createFrame();
} //constructor
public void addButtonListener() {
newItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
arrayList.add("data");
textPane = new JTextPane[arrayList.size()];
for(int i=0;i<arrayList.size();i++) {
textPane[i]=new JTextPane();
textPane[i].setText((String) arrayList.get(i));
addComponent(panel, gbl, textPane[i], 1, counter, 1, 1,1,1);
counter++;
}
}
});
}
public void addComponent(Container cont,
GridBagLayout gbl,
Component c,
int x, int y,
int width, int height,
double weightx, double weighty) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = x; gbc.gridy = y;
gbc.gridwidth = width; gbc.gridheight = height;
gbc.weightx = weightx; gbc.weighty = weighty;
gbl.setConstraints( c, gbc );
cont.add( c );
}
public void createFrame() {
frame.getContentPane().setLayout(new FlowLayout());
frame.add(scrollbar);
frame.add(newItem);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(300,300));
frame.setVisible(true);
}
public static void main(String [] args) {
new RefreshPanel();
}
}
But there is a little something which won't work: the items appears when I change the size of the frame, but I don't know why... any ideas?
thanks!

JFreeChart Horizontal Charts

I'm using CombinedDomainXYPlot to plot the charts. I have another requirement where, I need to show the two charts horizontally.
Currently i'm having only one chart. what i need is, i need two charts in the first row.
like Chart1 Chart2
Code:
CombinedDomainXYPlot plot = new CombinedDomainXYPlot();
plot.add(getChart1(), 2);
plot.add(getChart2(), 2);
It is giving only one chart in the first row. and second chart2 in the another row.
Is there any way I can make these two charts into single row?
Edit: Actually I wanted it like your ThermometerDemo example. For that you have used JPanel, but here I'm using JFrame.
I wanted it like your ThermometerDemo example.
Based on this example, the code below adds two panels to a GridLayout(1, 0). Each panel includes it's own chart and control panel.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.*;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
/**
* #see https://stackoverflow.com/a/20243624/230513
* #see https://stackoverflow.com/q/11870416/230513
*/
public class CombinedPlot {
private static final int MAX = 3;
private static final Random rand = new Random();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
init();
}
});
}
private static void init() {
JFrame frame = new JFrame("Combined Plot Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(1, 0));
frame.add(createPanel());
frame.add(createPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static JPanel createPanel() {
JPanel p = new JPanel(new BorderLayout());
XYItemRenderer renderer = new StandardXYItemRenderer();
XYPlot plot1 = new XYPlot(
generateData(), null, new NumberAxis("Range 1"), renderer);
XYPlot plot2 = new XYPlot(
generateData(), null, new NumberAxis("Range 2"), renderer);
final CombinedDomainXYPlot plot
= new CombinedDomainXYPlot(new NumberAxis("Domain"));
plot.add(plot1);
plot.add(plot2);
plot.setOrientation(PlotOrientation.VERTICAL);
JFreeChart chart = new JFreeChart(
"Combined Plots", JFreeChart.DEFAULT_TITLE_FONT, plot, false);
ChartPanel chartPanel = new ChartPanel(chart) {
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 320);
}
};
JPanel controlPanel = new JPanel();
controlPanel.add(new JButton(new UpdateAction(plot, 0)));
controlPanel.add(new JButton(new UpdateAction(plot, 1)));
p.add(chartPanel, BorderLayout.CENTER);
p.add(controlPanel, BorderLayout.SOUTH);
return p;
}
private static class UpdateAction extends AbstractAction {
private final XYPlot plot;
public UpdateAction(CombinedDomainXYPlot plot, int i) {
super("Update plot " + (i + 1));
this.plot = (XYPlot) plot.getSubplots().get(i);
}
#Override
public void actionPerformed(ActionEvent e) {
plot.setDataset(CombinedPlot.generateData());
}
}
private static XYSeriesCollection generateData() {
XYSeriesCollection data = new XYSeriesCollection();
for (int i = 0; i < MAX; i++) {
data.addSeries(generateSeries("Series " + (i + 1)));
}
return data;
}
private static XYSeries generateSeries(String key) {
XYSeries series = new XYSeries(key);
for (int i = 0; i < 16; i++) {
series.add(rand.nextGaussian(), rand.nextGaussian());
}
return series;
}
}

Resources