Hi, I got kind of a newbie question on how to prop...
# compose-desktop
e
Hi, I got kind of a newbie question on how to properly hoist state when using a SwingPanel inside my Composable… When my application starts, the UI contains a few ui components. One of them is JFreeChart which is hosted inside a JPanel which I add inside a SwingPanel composable. Something like that:
Copy code
var chartFrame: ChartPanel? = null

@Composable
private fun TheChart() {
    Card(elevation = 5.dp, shape = RoundedCornerShape(0.dp), modifier = Modifier.fillMaxSize()) {
        if (chartFrame == null) {
            val series = XYSeries("Sensors Reading")
            series.add(0, 3)
            series.add(1, 4)
            series.add(2, 5)
            series.add(3, 6)
            series.add(4, 7)
            series.add(5, 3)
            val dataset = XYSeriesCollection(series)
            val chart: JFreeChart = ChartFactory.createXYLineChart("Test", "Time (seconds)", "Sensors value", dataset)
            val frame = ChartPanel(chart)
            frame.isVisible = true
            chartFrame = frame
        }

        Box {
            SwingPanel(
                factory = {
                    JPanel().apply {
                        layout = BoxLayout(this, BoxLayout.Y_AXIS)
                        add(chartFrame)
                    }
                })
        }
    }
}
This renders great and looks as it should. Now, when I want to push in new data, I basically need to update the dataset, and I do that by adding x,y values to the series object. Now obviously this needs to be hoisted out of the Composable and get pushed into the function as a parameter. But I am not entirely sure on how to architect that properly in Compose. I also added a check for null to make sure not to recreate the chart object on each recomposition and I think this is not ideal here. Can any one assist?
d
I won't say that this is the best way because I've only been using compose for 6 months, and as a solo hobbyist, but what I do is: elsewhere:
Copy code
val series = remember { ... } // note the `=` instead of `by`

// update the series
series.value = newSeriesValue
and then
Copy code
private fun TheChart(series: State<XYSeries>) {
  ...
  val dataset = XYSeriesCollection(series.value)
  ...
hm, perhaps I misunderstood the problem
still, maybe that tidbit of using
State
directly will be of use
e
First of all thank you for replying 🙂 So in essence, you are saying I should pass into the TheChart function a State<XYSeries> and then when I update it out side lets say in another class entirely… it will also update the chart itself…
👍 1
Do you think the null check in that function might be an issue? I mean the point where I if (chartFrame == null)
I’m not entirely sure whether I need that null check or not…
d
up to you if it's nullable or not
if yes, then add a null check
e
Understood. Alright I’ll try it right now 🙂 Thank you