Why wrap GenericRowWithSchema using InternalRow in Dataset.collectFromPlan - apache-spark-sql

Look at Dataset.collectFromPlan
private def collectFromPlan(plan: SparkPlan): Array[T] = {
val objProj = GenerateSafeProjection.generate(deserializer :: Nil)
plan.executeCollect().map { row =>
objProj(row).get(0, null).asInstanceOf[T]
}
}
the generated code for objProj is:
class SpecificSafeProjection extends org.apache.spark.sql.catalyst.expressions.codegen.BaseProjection {
private Object[] references;
private InternalRow mutableRow;
private Object[] values;
private org.apache.spark.sql.types.StructType schema;
public SpecificSafeProjection(Object[] references) {
this.references = references;
mutableRow = (InternalRow) references[references.length - 1];
schema = (org.apache.spark.sql.types.StructType) references[0];
}
public void initialize(int partitionIndex) {
}
public java.lang.Object apply(java.lang.Object _i) {
........
final org.apache.spark.sql.Row value = new org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema(values, schema);
if (false) {
mutableRow.setNullAt(0);
} else {
mutableRow.update(0, value);
}
return mutableRow;
}
}
And my question is:
The generated method SpecificSafeProjection.apply returns mutableRow: InternalRow who wraps value:GenericRowWithSchema, why not return value:GenericRowWithSchema directly??

Related

Kotlin: correct way for read-only getters

I have a Java class (simplified) like that
public class Input {
private boolean leftPressed;
private boolean rightPressed;
public void handleValue(Event event) {
if (event.button == 1) {
leftPressed = event.pressed;
}
else if (event.button == 3) {
rightPressed = event.pressed;
}
}
public boolean isLeftPressed() {
return leftPressed;
}
public boolean isRightPressed() {
return rightPressed;
}
}
Note, that the fields only can be changed by code inside handleValue. Would this Kotlin code
class Input {
var leftPressed = false
private set
var rightPressed = false
private set
handleValue(event: Event) {
if (event.button == 1) {
leftPressed = event.pressed;
}
else if (event.button == 3) {
rightPressed = event.pressed;
}
}
}
be the proper way of creating the read-only properties? You really have to add the private set to make it safe/read-only? Are there other/better ways to prevent writing to the field from outside this class?

Hibernate QueryException Named parameter not bound error

I keep getting the error org.hibernate.QueryException: Named parameter not bound : item when I start my transaction in JPA using EntityManager createNativeQuery. I have my code below utilizing the entity manager, along with my embeddedID class (for the composite key) and my persistence entity bean. Is there a problem in my query syntax? I am not sure as I've tried multiple ways of formatting the sql (coming from a properties file where there resides multiple sqls used throughout the project, and attempting to persist data to an oracle db). I am not sure why I keep falling on this error. I want to persist this data to my oracle database but this error keeps preventing that.
Query from query.properties file:
insertPromoData =INSERT INTO TEST.U_USER_PROMO (ITEM, LOC, WK_START, NUMBER_OF_WEEKS, TYPE, FCSTID, QTY, U_TIMESTAMP) VALUES (:item, :location, :wkStart, :numberOfWeeks, :type, :fcstId, :quantity, SYSDATE)
Embeddedable Class for establishing composite primary key on the target table:
#Embeddable
public class PromoID implements Serializable {
#Column(name = "ITEM")
private String item;
#Column(name = "LOC")
private String loc;
#Column(name = "WK_START")
private Date weekStart;
#Column(name = "TYPE")
private int type;
#Column(name = "FCSTID")
private String forecastId;
#Column(name = "U_TIMESTAMP")
private Timestamp insertTS;
public PromoID() {
}
public PromoID (String item, String loc, Date weekStart, int type, String forecastId, Timestamp insertTS) {
this.item = item;
this.loc = loc;
this.weekStart = weekStart;
this.type = type;
this.forecastId = forecastId;
this.insertTS = insertTS;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Date getWeekStart() {
return weekStart;
}
public void setWeekStart(Date weekStart) {
this.weekStart = weekStart;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getForecastId() {
return forecastId;
}
public void setForecastId(String forecastId) {
this.forecastId = forecastId;
}
public Timestamp getInsertTS() {
return insertTS;
}
public void setInsertTS(Timestamp insertTS) {
this.insertTS = insertTS;
}
//removed hashcode and equals methods for simplicity
Persistence Entity Bean:
#Entity
#Table(name = "U_USER_PROMO")
public class InsertPromoData {
#EmbeddedId
private PromoID id;
/*#Column(name="BATCH_ID")
String batchID;*/
#Column(name="ITEM")
String item;
#Column(name="LOC")
String loc;
#Column(name="WK_START")
String weekStart;
#Column(name="TYPE")
String type;
#Column(name="FCSTID")
String forecastId;
#Column(name="U_TIMESTAMP")
String insertTS;
#Column(name="NUMBER_OF_WEEKS")
String numberOfWeeks;
#Column(name="QTY")
String qty;
#Id
#AttributeOverrides(
{
#AttributeOverride(name = "item",column = #Column(name="ITEM")),
#AttributeOverride(name = "loc", column = #Column(name="LOC")),
#AttributeOverride(name = "weekStart", column = #Column(name="WK_START")),
#AttributeOverride(name = "type", column = #Column(name="TYPE")),
#AttributeOverride(name = "forecastId", column = #Column(name="FCSTID"))
}
)
public PromoID getId() {
return id;
}
public void setId(PromoID id) {
this.id = id;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public String getWeekStart() {
return weekStart;
}
public void setWeekStart(String weekStart) {
this.weekStart = weekStart;
}
public String getNumberOfWeeks() {
return numberOfWeeks;
}
public void setNumberOfWeeks(String numberOfWeeks) {
this.numberOfWeeks = numberOfWeeks;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getForecastId() {
return forecastId;
}
public void setForecastId(String forecastId) {
this.forecastId = forecastId;
}
public String getQty() {
return qty;
}
public void setQty(String qty) {
this.qty = qty;
}
public String getInsertTS() {
return insertTS;
}
public void setInsertTS(String insertTS) {
this.insertTS = insertTS;
}
}
My dao OracleImpl.java using EntityManager for persisting:
public void insertPromoData(List<InsertPromoData> insertData) {
logger.debug("Execution of method insertPromoData in Dao started");
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
System.out.println("Beginning transaction for insertPromoData");
Query query = em.createNativeQuery(env.getProperty("insertPromoData"));
for (InsertPromoData promoData : insertData) {
query.setParameter("item", promoData.getItem());
query.setParameter("location", promoData.getLoc());
query.setParameter("wkStart", promoData.getWeekStart());
query.setParameter("numberOfWeeks", promoData.getNumberOfWeeks());
query.setParameter("type", promoData.getType());
query.setParameter("fcstId", promoData.getForecastId());
query.setParameter("quantity", Double.valueOf(promoData.getQty()));
}
query.executeUpdate();
System.out.println("Data for promo persisted");
em.getTransaction().commit();
}
catch(Exception e) {
logger.error("Exception in beginning transaction");
e.printStackTrace();
}
finally {
em.clear();
em.close();
}
logger.debug("Execution of method insertPromoData in Dao ended");
}
PromoValidator.java class:
List <InsertPromoData> insertPromos = new ArrayList<>();
promo.forEach(record -> {
if (record.getErrorList().size() == 0) {
rowsSuccessful++;
record.setItem(record.getItem());
record.setLoc(record.getLoc());
record.setNumber_Of_Weeks(record.getNumber_Of_Weeks());
record.setForecast_ID(record.getForecast_ID());
record.setType(record.getType());
record.setUnits(record.getUnits());
record.setWeek_Start_Date(record.getWeek_Start_Date());
insertPromos = (List<InsertPromoData>) new InsertPromoData();
for (InsertPromoData insertPromoData : insertPromos) {
insertPromoData.setItem(record.getItem());
insertPromoData.setLoc(record.getLoc());
insertPromoData.setWeekStart(LocalDate.parse(record.getWeek_Start_Date()));
insertPromoData.setNumberOfWeeks(Integer.parseInt(record.getNumber_Of_Weeks()));
insertPromoData.setType(Integer.parseInt(record.getType()));
insertPromoData.setForecastId(record.getForecast_ID());
insertPromoData.setQty(Double.parseDouble(record.getUnits()));
}
} else {
if (rowsFailure == 0) {
Util.writeHeaderToFile(templateCd, errorFile);
}
rowsFailure++;
Util.writeErrorToFile(templateCd, errorFile, record, record.getErrorList());
}
});
errorFile.close();
successFile.close();
OracleImpl.insertPromoData(insertPromos);
One of the reason this can happen is when insertData List you are passing is empty.
If I use below code ( please note that I have removed few columns to simplify it on my test environment with H2 database) - I get the error you described if empty list is passed and that's because there is indeed nothing to bind for the name parameter as the loop is not executed.
try {
em.getTransaction().begin();
System.out.println("Beginning transaction for insertPromoData");
Query query = em.createNativeQuery(
"INSERT INTO U_USER_PROMO (ITEM, LOC, WK_START, NUMBER_OF_WEEKS, TYPE, FCSTID, QTY) VALUES (:item, :location, :wkStart, :numberOfWeeks, :type, :fcstId, :quantity)");
for (InsertPromoData promoData : insertData) {
query.setParameter("item", promoData.getId().getItem());
query.setParameter("location", promoData.getId().getLoc());
query.setParameter("wkStart", promoData.getId().getWeekStart());
query.setParameter("numberOfWeeks", promoData.getNumberOfWeeks());
query.setParameter("type", promoData.getId().getType());
query.setParameter("fcstId", promoData.getId().getForecastId());
query.setParameter("quantity", Double.valueOf(promoData.getQty()));
}
query.executeUpdate();
System.out.println("Data for promo persisted");
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
em.clear();
em.close();
}
The error I get is
org.hibernate.QueryException: Named parameter not bound : item
at org.hibernate.query.internal.QueryParameterBindingsImpl.verifyParametersBound(QueryParameterBindingsImpl.java:210)
at org.hibernate.query.internal.AbstractProducedQuery.beforeQuery(AbstractProducedQuery.java:1425)
at org.hibernate.query.internal.NativeQueryImpl.beforeQuery(NativeQueryImpl.java:249)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1610)
at com.danielme.blog.nativesql.dao.UserDao.insertPromoData(UserDao.java:99)
However - if I pass non-empty list - this works as expected
SQLCustomQuery:72 - Starting processing of sql query [INSERT INTO U_USER_PROMO (ITEM, LOC, WK_START, NUMBER_OF_WEEKS, TYPE, FCSTID, QTY) VALUES (:item, :location, :wkStart, :numberOfWeeks, :type, :fcstId, :quantity)]
AbstractFlushingEventListener:74 - Flushing session
I also encountered same problem. I noticed that I was defining the parameter in the query but I was not setting its value in:
query.setParameter(parameterToBeSet,parameterValue)
For example,
String hql = "FROM COLLEGE FETCH ALL PROPERTIES WHERE studentId = :studentId AND departmentId = :departmentId AND studentName = :studentName";
DBConnectionManager.getInstance().invokeCallableOnSessionMasterDB(session -> {
Query<CollegeEntity> query = session.createQuery(hql);
query.setParameter("studentId", studentId);
query.setParameter("departmentId", departmentId);
values.addAll(query.list());
});
As you can see the student name value was not set. So, after adding:
query.setParameter("studentName", studentName);
It got solved.
GETRequest : localhost:8080/getbyCity/chennai,mumbai,kolkata -
error ---> when I send this request I got------->"Hibernate QueryException Named parameter not bound error".
Answer: when we send list of parameter we should mention the "/" at the End. ((( localhost:8080/getbyCity/chennai,mumbai,kolkata/ ))). Set the bound using "/".
In my case I have put same parameter name to the procedure as:
#Param("managementAccess") Boolean managementAccess,
#Param("managementAccess") String dealerCode,
#Param("managementAccess") String dealerName,
Here the parameter name is different but inside string the name is same.
Solution is:
#Param("managementAccess") Boolean managementAccess,
#Param("dealerCode") String dealerCode,
#Param("dealerName") String dealerName,

JTable for JPanel with multiple type JComponent (Swing)

This is a long question, but all code is needed (I was thinking a basic question, with not common components).
I need to build a JTable with multiple Columns with multiple type Custom JPanel (with JSlider + JComboBox + JTextField) in only one Column.
I was reading: http://pekalicious.com/blog/custom-jpanel-cell-with-jbuttons-in-jtable/
In this question, I will use one Column with only one Customized JPanel with name PanelSpinnerRadioButton.
The Custom Panel:PanelSpinnerRadioButton.java
public class PanelSpinnerRadioButton extends JPanel {
private final JRadioButton jrbOption01= new JRadioButton("01");
private final JRadioButton jrbOption02 = new JRadioButton("12");
private final JSpinner jspnValues = new JSpinner(new SpinnerNumberModel(5, 0, 10, 1));
private final JPanel jpPanelSpinnerRadioButton = new JPanel();
PanelSpinnerRadioButton() {
this(new PanelSpinnerRadioButtonData(false, 20, 40));
}
PanelSpinnerRadioButton(PanelSpinnerRadioButtonData data) {
super();
jpPanelSpinnerRadioButton.setLayout(new BoxLayout(jpPanelSpinnerRadioButton, BoxLayout.LINE_AXIS));
jpPanelSpinnerRadioButton.add(jrbOption01);
jpPanelSpinnerRadioButton.add(jrbOption02);
jpPanelSpinnerRadioButton.add(Box.createRigidArea(new Dimension(5,0)));
jpPanelSpinnerRadioButton.add(new JSeparator(JSeparator.VERTICAL));
jpPanelSpinnerRadioButton.add(Box.createRigidArea(new Dimension(5,0)));
jpPanelSpinnerRadioButton.add(jspnValues);
//Change States of RadioButtons (will be readOnly, ButtonGroup is not needed)
jrbOption02.setSelected(data.getOption());
jrbOption01.setSelected(!data.getOption());
//Change States of Spinner
((SpinnerNumberModel)jspnValues.getModel()).setValue(data.getFrom());
((SpinnerNumberModel)jspnValues.getModel()).setMaximum(data.getSize());
init();
}
private void init() {
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
setBackground(new Color(0, 0, 0, 0/*64*/));
add(jpPanelSpinnerRadioButton);
}
// Used in PSRBTableCellEditor.getCellEditorValue()
public PanelSpinnerRadioButtonData getData() {
return new PanelSpinnerRadioButtonData(
jrbOption02.isSelected(),
(Integer)((SpinnerNumberModel)jspnValues.getModel()).getValue(),
(Integer)((SpinnerNumberModel)jspnValues.getModel()).getMaximum()
);
}
}
Here the Image Result of before Custom JPanel
Data Type for Custom Panel:PanelSpinnerRadioButtonData.java
public class PanelSpinnerRadioButtonData {
private boolean opt02 = false;
private Integer from = 0;
private Integer size = 1;
PanelSpinnerRadioButtonData() {
this(false, 5, 10);
}
PanelSpinnerRadioButtonData(boolean opt02, Integer from, Integer size) {
this.opt02 = opt02;
this.from = from;
this.size = size;
}
public boolean getOption() { return opt02; }
public Integer getFrom() { return from; }
public Integer getSize() { return size; }
}
Now the coded to handle my Custom JPanel (with inner JComponents)
the Table Model:PSRBTableModel.java
public class PSRBTableModel extends AbstractTableModel {
private final Object[][] data;
private final Object[] columns;
public PSRBTableModel(Object[][] data, Object[] columns) {
// super();
this.data = data;
this.columns = columns;
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (data != null) {
if (data.length > 0) {
if (data[rowIndex][columnIndex] instanceof PanelSpinnerRadioButton) {
return (PanelSpinnerRadioButton)data[rowIndex][columnIndex];
}
return data[rowIndex][columnIndex];
}
}
return null;
}
public int getColumnCount() {
return ((columns == null) ? 0: columns.length);
}
public int getRowCount() {
return ((data == null) ? 0: data.length);
}
public Class getColumnClass(int columnIndex) {
if (data != null) {
if (data.length > 0) {
if (data[0][columnIndex] instanceof PanelSpinnerRadioButton) {
return PanelSpinnerRadioButton.class;
}
return data[0][columnIndex].getClass();
}
}
return null;
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
if (data != null) {
if (data.length > 0) {
if (data[0][columnIndex] instanceof PanelSpinnerRadioButton) {
//PanelSpinnerRadioButton Is not Editable
return false;
}
}
}
return true;
}
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
public String getColumnName(int columnIndex) {
return (String)columns[columnIndex];
}
}
Now the Renderer:PSRBTableCellRenderer.java
public class PSRBTableCellRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Object output = null;
if (value instanceof PanelSpinnerRadioButtonData) {
output = new PanelSpinnerRadioButton((PanelSpinnerRadioButtonData)value);
}
return (Component)output;
}
}
And the EditorCell:PSRBTableCellEditor.java
public class PSRBTableCellEditor extends AbstractCellEditor implements TableCellEditor {
protected Object output;
PSRBTableCellEditor() {
}
public Object getCellEditorValue() {
//Returns the value contained in the editor.
if (output instanceof PanelSpinnerRadioButton) {
return ((PanelSpinnerRadioButton)output).getData();
}
return null;
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
//Sets an initial value for the editor.
if (value instanceof PanelSpinnerRadioButtonData) {
output = new PanelSpinnerRadioButton((PanelSpinnerRadioButtonData)value);
return (PanelSpinnerRadioButton)output;
}
return null;
}
}
Test the Before Code (I'm working with JFrame)
String[] hdrsObjects = new String[]{"PanelSpinnerRadioButton Class Column"};
Object[][] objectMatrix = new Object[3][hdrsObjects.length];
objectMatrix[0][0] = new PanelSpinnerRadioButton();
objectMatrix[1][0] = new PanelSpinnerRadioButton();
objectMatrix[2][0] = new PanelSpinnerRadioButton();
JTable jtbl = new JTable(new PSRBTableModel(objectMatrix, hdrsObjects));
//jtbl.setDefaultRenderer(PanelSpinnerRadioButton.class, new PSRBTableCellRenderer());
//jtbl.setDefaultEditor(PanelSpinnerRadioButton.class, new PSRBTableCellEditor());
jtbl.getColumn("PanelSpinnerRadioButton Class Column").setCellRenderer(new PSRBTableCellRenderer());
jtbl.getColumn("PanelSpinnerRadioButton Class Column").setCellEditor(new PSRBTableCellEditor());
add(new JScrollPane(jtbl));
But I can't see the JTable with (3 rows with Custom JPanel 'PanelSpinnerRadioButton')
I have this exception...
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.plaf.synth.SynthTableUI.paintCell(SynthTableUI.java:684)
at javax.swing.plaf.synth.SynthTableUI.paintCells(SynthTableUI.java:580)
at javax.swing.plaf.synth.SynthTableUI.paint(SynthTableUI.java:364)
at javax.swing.plaf.synth.SynthTableUI.update(SynthTableUI.java:275)
at javax.swing.JComponent.paintComponent(JComponent.java:780)
at javax.swing.JComponent.paint(JComponent.java:1056)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JViewport.paint(JViewport.java:728)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5217)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:306)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent.paint(JComponent.java:1042)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:79)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:116)
at java.awt.Container.paint(Container.java:1975)
at java.awt.Window.paint(Window.java:3912)
at javax.swing.RepaintManager$4.run(RepaintManager.java:842)
at javax.swing.RepaintManager$4.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access$1200(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
QUESTION
What's wrong?
Why I can't see the JTable with 3 PanelSpinnerRadioButton?
EDITION
Please consider this scenario (Another Custom JPanel handled by the same TableCellRenderer PSRBTableCellRenderer and TableCellEditor PSRBTableCellEditor)
class PanelButton extends JPanel {
private final JPanel jpPanelButton = new JPanel();
// the ActionListener does not matter now
JButton jbtAction = new JButton("Action");
PanelButton() {
this(new PanelButtonEmpty());
}
PanelButton(PanelButtonEmpty data) {
super();
jpPanelButton.setLayout(new BoxLayout(jpPanelButton, BoxLayout.LINE_AXIS));
jpPanelButton.add(jbtAction);
/*Overridable method call in constructor*/
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
setBackground(new Color(0, 0, 0, 0/*64*/));
add(jpPanelButton);
}
public PanelButtonEmpty getData() {
return new PanelButtonEmpty();
}
public void setData(PanelButtonEmpty data) {
}
}
I was thinking in a totally empty class (to cast the value in TableCellRenderer PSRBTableCellEditor)
class PanelButtonEmpty {
PanelButtonEmpty() { }
//public boolean getLazy() { return true; }
//public void setLazy(boolean b) {}
}
In this case I have two types of Custom JPanel for this reason I have
for TableCellEditor
public class PSRBTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private Object output;
#Override public Object getCellEditorValue() {
if (output instanceof PanelSpinnerRadioButton) {
return ((PanelSpinnerRadioButton)output).getData();
}
if (output instanceof PanelButton) {
return ((PanelButton)output).getData();
}
return null;
}
#Override public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
output = new PanelSpinnerRadioButton((PanelSpinnerRadioButtonData)value);
return (PanelSpinnerRadioButton)output;
}
if (value instanceof PanelButtonEmpty) {
output = new PanelButton((PanelButtonEmpty)value);
return (PanelButton)output;
}
return null;
}
}
for TableCellRenderer
public class PSRBTableCellRenderer implements TableCellRenderer {
private Object output = null;
#Override public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
output = new PanelSpinnerRadioButton((PanelSpinnerRadioButtonData)value);
}
if (value instanceof PanelButtonEmpty) {
output = new PanelButton((PanelButtonEmpty)value);
}
return (Component)output;
}
}
QUESTIONS
How to avoid your Second Warning (in the new scenario)?
It is a waste to create each time a component in the TableCellRenderer#getTableCellRendererComponent(...).
How to handle with Objects different to here described?
PD:
I'm not sure to put this second part question in another post with the same source code...
objectMatrix[0][0] = new PanelSpinnerRadioButton();
Should be set PanelSpinnerRadioButtonData to the TableModel, rather than a component such as PanelSpinnerRadioButton.
output = new PanelSpinnerRadioButton((PanelSpinnerRadioButtonData)value);
It is a waste to create each time a component in the TableCellRenderer#getTableCellRendererComponent(...).
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableTest {
public JComponent makeUI() {
String[] hdrsObjects = {"PanelSpinnerRadioButton Class Column"};
Object[][] objectMatrix = new Object[3][hdrsObjects.length];
objectMatrix[0][0] = new PanelSpinnerRadioButtonData(false, 10, 40);
objectMatrix[1][0] = new PanelSpinnerRadioButtonData(true, 20, 40);
objectMatrix[2][0] = new PanelSpinnerRadioButtonData(false, 30, 40);
JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects));
table.setRowHeight(30);
TableColumn tc = table.getColumn("PanelSpinnerRadioButton Class Column");
tc.setCellRenderer(new PSRBTableCellRenderer());
tc.setCellEditor(new PSRBTableCellEditor());
JPanel p = new JPanel(new BorderLayout());
p.add(new JScrollPane(table));
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
try {
for (UIManager.LookAndFeelInfo laf: UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(laf.getName())) {
UIManager.setLookAndFeel(laf.getClassName());
}
}
} catch (Exception e) {
e.printStackTrace();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TableTest().makeUI());
f.setSize(240, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
class PanelSpinnerRadioButtonData {
private boolean opt02 = false;
private Integer from = 0;
private Integer size = 1;
PanelSpinnerRadioButtonData() {
this(false, 5, 10);
}
PanelSpinnerRadioButtonData(boolean opt02, Integer from, Integer size) {
this.opt02 = opt02;
this.from = from;
this.size = size;
}
public boolean getOption() {
return opt02;
}
public Integer getFrom() {
return from;
}
public Integer getSize() {
return size;
}
}
class PanelSpinnerRadioButton extends JPanel {
public final JRadioButton jrbOption01 = new JRadioButton("01");
public final JRadioButton jrbOption02 = new JRadioButton("12");
public final JSpinner jspnValues = new JSpinner(new SpinnerNumberModel(5, 0, 10, 1));
private final JPanel panel = new JPanel();
PanelSpinnerRadioButton() {
this(new PanelSpinnerRadioButtonData(false, 20, 40));
}
PanelSpinnerRadioButton(PanelSpinnerRadioButtonData data) {
super();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(jrbOption01);
panel.add(jrbOption02);
panel.add(Box.createRigidArea(new Dimension(5, 0)));
panel.add(new JSeparator(JSeparator.VERTICAL));
panel.add(Box.createRigidArea(new Dimension(5, 0)));
panel.add(jspnValues);
ButtonGroup bg = new ButtonGroup();
bg.add(jrbOption01);
bg.add(jrbOption02);
((SpinnerNumberModel) jspnValues.getModel()).setMaximum(data.getSize());
setData(data);
init();
}
private void init() {
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
setBackground(new Color(0, 0, 0, 0));
add(panel);
}
public void setData(PanelSpinnerRadioButtonData data) {
if (data.getOption()) {
jrbOption02.setSelected(true);
} else {
jrbOption01.setSelected(true);
}
((SpinnerNumberModel) jspnValues.getModel()).setValue(data.getFrom());
}
// Used in PSRBTableCellEditor.getCellEditorValue()
public PanelSpinnerRadioButtonData getData() {
return new PanelSpinnerRadioButtonData(
jrbOption02.isSelected(),
(Integer) ((SpinnerNumberModel) jspnValues.getModel()).getValue(),
(Integer) ((SpinnerNumberModel) jspnValues.getModel()).getMaximum());
}
}
class PSRBTableCellRenderer implements TableCellRenderer {
private final PanelSpinnerRadioButton renderer = new PanelSpinnerRadioButton();
#Override public Component getTableCellRendererComponent(
JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
renderer.setData((PanelSpinnerRadioButtonData) value);
}
return renderer;
}
}
class PSRBTableCellEditor extends AbstractCellEditor implements TableCellEditor {
private final PanelSpinnerRadioButton editor = new PanelSpinnerRadioButton();
#Override public Object getCellEditorValue() {
return editor.getData();
}
#Override public Component getTableCellEditorComponent(
JTable table, Object value, boolean isSelected, int row, int column) {
if (value instanceof PanelSpinnerRadioButtonData) {
editor.setData((PanelSpinnerRadioButtonData) value);
}
return editor;
}
}

Oracle Coherence index not working with ContainsFilter query

I've added an index to a cache. The index uses a custom extractor that extends AbstractExtractor and overrides only the extract method to return a List of Strings. Then I have a ContainsFilter which uses the same custom extractor that looks for the occurence of a single String in the List of Strings. It does not look like my index is being used based on the time it takes to execute my test. What am I doing wrong? Also, is there some debugging I can switch on to see which indices are used?
public class DependencyIdExtractor extends AbstractExtractor {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public Object extract(Object oTarget) {
if (oTarget == null) {
return null;
}
if (oTarget instanceof CacheValue) {
CacheValue cacheValue = (CacheValue)oTarget;
// returns a List of String objects
return cacheValue.getDependencyIds();
}
throw new UnsupportedOperationException();
}
}
Adding the index:
mCache = CacheFactory.getCache(pCacheName);
mCache.addIndex(new DependencyIdExtractor(), false, null);
Performing the ContainsFilter query:
public void invalidateByDependencyId(String pDependencyId) {
ContainsFilter vContainsFilter = new ContainsFilter(new DependencyIdExtractor(), pDependencyId);
#SuppressWarnings("rawtypes")
Set setKeys = mCache.keySet(vContainsFilter);
mCache.keySet().removeAll(setKeys);
}
I solved this by adding a hashCode and equals method implementation to the DependencyIdExtractor class. It is important that you use exactly the same value extractor when adding an index and creating your filter.
public class DependencyIdExtractor extends AbstractExtractor {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public Object extract(Object oTarget) {
if (oTarget == null) {
return null;
}
if (oTarget instanceof CacheValue) {
CacheValue cacheValue = (CacheValue)oTarget;
return cacheValue.getDependencyIds();
}
throw new UnsupportedOperationException();
}
#Override
public int hashCode() {
return 1;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj instanceof DependencyIdExtractor) {
return true;
}
return false;
}
}
To debug Coherence indices/queries, you can generate an explain plan similar to database query explain plans.
http://www.oracle.com/technetwork/tutorials/tutorial-1841899.html
#SuppressWarnings("unchecked")
public void invalidateByDependencyId(String pDependencyId) {
ContainsFilter vContainsFilter = new ContainsFilter(new DependencyIdExtractor(), pDependencyId);
if (mLog.isTraceEnabled()) {
QueryRecorder agent = new QueryRecorder(RecordType.EXPLAIN);
Object resultsExplain = mCache.aggregate(vContainsFilter, agent);
mLog.trace("resultsExplain = \n" + resultsExplain + "\n");
}
#SuppressWarnings("rawtypes")
Set setKeys = mCache.keySet(vContainsFilter);
mCache.keySet().removeAll(setKeys);
}

ChoiceBox with custom Item in a TableView

I have a
private TableView<Indicators> tableviewIndicators;
with column
private TableColumn<Indicators, WindowsItem> tablecolumnFrame;
public static class WindowsItem {
CustomInternalWindow chrt;
private WindowsItem(CustomInternalWindow _chrt) {
chrt = _chrt;
}
public String toString() {
return chrt.getTitle();
}
}
private Indicators(String tl, WindowsItem chrt, String pne, Boolean sel) {
this.tool_col = new SimpleStringProperty(tl);
if (chrt == null) {
this.chart_col = new SimpleStringProperty("");
} else {
this.chart_col = new SimpleStringProperty(chrt.toString());
}
this.pane_col = new SimpleStringProperty(pne);
this.on_col = new SimpleBooleanProperty(sel);
this.chrt = chrt;
}
public String getTool() {
return tool_col.get();
}
public void setTool(String tl) {
tool_col.set(tl);
}
public WindowsItem getChart() {
return chrt;
}
public void setChart(WindowsItem _chrt) {
System.out.println("Indicators::setChart "+chrt.toString());
chrt = _chrt;
}
public String getPane() {
return pane_col.get();
}
public void setPane(String pne) {
pane_col.set(pne);
}
public Boolean getOn() {
return on_col.get();
}
public void setOn(boolean sel) {
on_col.set(sel);
}
public SimpleBooleanProperty onProperty() {
return on_col;
}
public SimpleStringProperty toolProperty() {
return tool_col;
}
public SimpleStringProperty chartProperty() {
return chart_col;
}
public SimpleStringProperty paneProperty() {
return pane_col;
}
}
tablecolumnFrame.setCellValueFactory(new PropertyValueFactory<Indicators, WindowsItem>("chart"));
How can I add a combobox or choicebox in tablecolumnFrame?
The following code
tablecolumnFrame.setCellFactory(new Callback<TableColumn<Indicators, WindowsItem>, TableCell<Indicators, WindowsItem>>() {
#Override
public TableCell<Indicators, WindowsItem> call(TableColumn<Indicators, WindowsItem> param) {
TableCell<Indicators, WindowsItem> cell = new TableCell<Indicators, WindowsItem>() {
#Override
public void updateItem(WindowsItem item, boolean empty) {
super.updateItem(item, empty);
if(empty){
return;
}
if (item != null) {
//final ChoiceBox<WindowsItem> choice = new ChoiceBox<>();
final ComboBox<WindowsItem> choice = new ComboBox<>();
int itemsInTab = chartsInTab.getChildren().size();// dimensione del contenuto del tab, compreso il pane
CustomInternalWindow winItem;
//
for (int i = 0; i < itemsInTab; i++) {
if (chartsInTab.getChildren().get(i) instanceof CustomInternalWindow) {
winItem = (CustomInternalWindow) chartsInTab.getChildren().get(i);
choice.getItems().add(new WindowsItem(winItem));
//choice.getItems().add(winItem.toString());
System.out.println("winItem.toString() "+winItem.toString());
}
}
return this error
SEVERE: javafx.scene.control.Control loadSkinClass Failed to load skin 'StringProperty [bean: TableRow[id=null, styleClass=cell indexed-cell table-row-cell], name: skinClassName, value: com.sun.javafx.scene.control.skin.TableRowSkin]' for control TableRow[id=null, styleClass=cell indexed-cell table-row-cell]
Why do you need special property? You can create ListView with ComboBox quite easily:
ObservableList<WindowsItem> windowsItems = FXCollections.observableArrayList();
ObservableList<WindowsItem> data = FXCollections.observableArrayList();
final ListView<WindowsItem> listView = new ListView<>(data);
listView.setEditable(true);
listView.setItems(data);
listView.setCellFactory(ComboBoxListCell.forListView(windowsItems));